<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>아빠의 IT 이야기</title>
    <link>https://fathersit.tistory.com/</link>
    <description>IT, 시사, 정치, 투자, 일상</description>
    <language>ko</language>
    <pubDate>Sun, 26 Jul 2026 10:30:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>아빠아이티</managingEditor>
    <image>
      <title>아빠의 IT 이야기</title>
      <url>https://tistory1.daumcdn.net/tistory/5458431/attach/da9524180b26451a9d222f8978f3b79a</url>
      <link>https://fathersit.tistory.com</link>
    </image>
    <item>
      <title>안드로이드 앱 취약점 진단(feat. 안드로이드 소개,  설치방법 및 진단 환경 구성)</title>
      <link>https://fathersit.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;안드로이드란?(Android)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안드로이드란&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424;&quot;&gt;Android는 주로 스마트폰 및 태블릿과 같은 터치스크린 &lt;span style=&quot;color: #ee2323;&quot;&gt;모바일 장치용으로 설계된 Linux 커널 및 기타 오픈 소스 소프트웨어의 수정된 버전을 기반으로 하는 모바일 운영체제&lt;/span&gt;이며, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424;&quot;&gt;Open Handset Alliance로 알려진 개발자 컨소시엄에서 개발하고 구글에서 상업적으로 후원중. 안드로이드&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424;&quot;&gt; 기기의 아키텍처, 애플리케이션이 어떻게 컴파일되는지, 가장 중요한 것은 안드로이드 애플리케이션의 구성을 이해하는 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안드로이드의 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;하드웨어&lt;/b&gt;&lt;br /&gt;Android의 주요 하드웨어 플랫폼은 이후 릴리스에서도 지원되는 x86 및 x86-64 아키텍처가 있는 ARM Android 5.0 Lollipop부터 32비트 변형 외에도 모든 플랫폼의 64비트 변형이 지원됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;커널&lt;/b&gt; &lt;br /&gt;Android 커널은 Linux 커널의 LTS 분기를 기반으로 사용 &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;b&gt;파일 시스템&lt;/b&gt; &lt;br /&gt;Android 출시 이후로 YAFFS2를 사용 중이나, Android 2.3 이후에는 EXT4 파일 시스템을 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;안드로이드 파일 시스템은 파일 브라우저를 통해 탐색이 가능하며, 공장 초기화를 누르면 지워짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 디렉토리는 모든 Android에 기본적으로 있음 &lt;br /&gt;- 부팅: 파티션에는 전원이 켜질 때 전화가 부팅되는 데 필요한 커널, 램디스크 등이 포함 &lt;br /&gt;- 시스템: Android UI 및 사전 설치된 앱을 포함하는 OS 파일 포함 &lt;br /&gt;- 복구: OS로 부팅하는 대체 옵션으로 파티션을 복구하고 백업할 수 있음 &lt;br /&gt;- 데이터: 사용자 데이터, 앱 데이터, 메시징, 음악 등을 저장 &lt;br /&gt;&amp;nbsp; &lt;br /&gt;하위 폴더는 아래로 구성되어 있음 &lt;br /&gt;- Android: 앱 캐시 및 저장된 데이터의 기본값 &lt;br /&gt;- 알람: 알람에 대한 사용자 지정 오디오 파일&lt;br /&gt;- Cardboard: VR 파일에 대한 데이터를 포함 &lt;br /&gt;- DCIM: 카메라 앱으로 찍은 사진과 비디오를 저장 &lt;br /&gt;- 다운로드: 인터넷에서 다운로드한 파일을 저장 &lt;br /&gt;- 알림: 일부 앱의 알림에 대한 사용자 지정 톤&lt;br /&gt;- 음악, 영화: 타사 앱의 노래와 비디오를 저장하는 기본 폴더 &lt;br /&gt;- 사진: 타사 앱에서 찍은 사진을 저장하는 기본 폴더 &lt;br /&gt;- 캐시: 자주 사용하는 데이터 및 앱 구성 요소의 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;안드로이드 아키텍쳐&lt;/b&gt; &lt;br /&gt;- 커널&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;커널은 사용자가 하드웨어와 통신할 수 있는 인터페이스를 제공하는 Android OS의 가장 중요한 부분. 하드웨어 구성 요소가 특정 기능을 지시하기 위해 프로그램에서 사용하는 필수 드라이버가 포함되어 있음. 오디오,&amp;nbsp;디스플레이,&amp;nbsp;블루투스&amp;nbsp;등이&amp;nbsp;해당됨 &lt;br /&gt;&lt;br /&gt;- 하드웨어 추상화 계층 (Hard Abstraction Layer) &lt;br /&gt;컴퓨터의&amp;nbsp;물리적인&amp;nbsp;하드웨어와&amp;nbsp;소프트웨어&amp;nbsp;사이의&amp;nbsp;추상화&amp;nbsp;계층&amp;nbsp;역할을&amp;nbsp;하는&amp;nbsp;논리적&amp;nbsp;코드&amp;nbsp;분할 &lt;br /&gt;프로그램이&amp;nbsp;하드웨어와&amp;nbsp;통신할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;장치&amp;nbsp;드라이버&amp;nbsp;인터페이스를&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp; &lt;br /&gt;- 라이브러리 &lt;br /&gt;어플리케이션,&amp;nbsp;리소스&amp;nbsp;파일&amp;nbsp;및&amp;nbsp;매니페스트&amp;nbsp;개발을&amp;nbsp;위한&amp;nbsp;개발자&amp;nbsp;지원을&amp;nbsp;제공 &lt;br /&gt;네이티브&amp;nbsp;라이브러리는&amp;nbsp;네이티브&amp;nbsp;코드에서&amp;nbsp;작업을&amp;nbsp;효과적으로&amp;nbsp;수행하기&amp;nbsp;위해&amp;nbsp;필요함 &lt;br /&gt;&lt;br /&gt;- 안드로이드 런타임 (Android Run Time) &lt;br /&gt;안드로이드&amp;nbsp;OS에서&amp;nbsp;사용하는&amp;nbsp;애플리케이션&amp;nbsp;런타임&amp;nbsp;환경 &lt;br /&gt;프로그램이&amp;nbsp;프로세서에&amp;nbsp;명령을&amp;nbsp;보내고&amp;nbsp;컴퓨터의&amp;nbsp;RAM에&amp;nbsp;액세스할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;상태 &lt;br /&gt;자바로 프로그래밍된 안드로이드앱은 컴파일 중에 APK 및 실행 런타임으로 패키징되는 동안 먼저 바이트 코드로 변환됨 &lt;br /&gt;&lt;br /&gt;안드로이드는&amp;nbsp;가상&amp;nbsp;머신을&amp;nbsp;사용해&amp;nbsp;모든&amp;nbsp;응용&amp;nbsp;프로그램을&amp;nbsp;실행하여&amp;nbsp;OS에서&amp;nbsp;프로그램&amp;nbsp;실행을&amp;nbsp;격리하고&amp;nbsp;영향을&amp;nbsp;받는&amp;nbsp;시스템을&amp;nbsp;악성&amp;nbsp;코드로부터&amp;nbsp;보호함 &lt;br /&gt;&lt;br /&gt;Android&amp;nbsp;4.4&amp;nbsp;이전에는&amp;nbsp;DVM(Dalvik&amp;nbsp;Virtual&amp;nbsp;Machine)&amp;nbsp;이었다가&amp;nbsp;이후&amp;nbsp;ART로&amp;nbsp;대체됨 &lt;br /&gt;&lt;br /&gt;DVM은&amp;nbsp;JIT(Just&amp;nbsp;in&amp;nbsp;time)&amp;nbsp;컴파일을&amp;nbsp;사용하여&amp;nbsp;어플리케이션&amp;nbsp;코드를&amp;nbsp;가져와&amp;nbsp;분석하고&amp;nbsp;런타임으로&amp;nbsp;컴파일함 &lt;br /&gt;ART는&amp;nbsp;.dex파일이&amp;nbsp;필요하기도&amp;nbsp;전에&amp;nbsp;컴파일을&amp;nbsp;하는&amp;nbsp;AOT(ahead&amp;nbsp;of&amp;nbsp;time)&amp;nbsp;컴파일을&amp;nbsp;사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인시큐어뱅크 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 인시큐어뱅크란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인시큐어뱅크 버전2(insecurebankv2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모바일 뱅킹 취약점 진단을 위해 테스트 용도로 제작된 어플리케이션. 백엔드 서버는 파이썬으로 제작되었으며, 깃허브에서 다운로드 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://github.com/dineshshetty/Android-InsecureBankv2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/dineshshetty/Android-InsecureBankv2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643936205695&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - dineshshetty/Android-InsecureBankv2: Vulnerable Android application for developers and security enthusiasts to learn ab&quot; data-og-description=&quot;Vulnerable Android application for developers and security enthusiasts to learn about Android insecurities - GitHub - dineshshetty/Android-InsecureBankv2: Vulnerable Android application for develop...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/dineshshetty/Android-InsecureBankv2&quot; data-og-url=&quot;https://github.com/dineshshetty/Android-InsecureBankv2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iHOme/hyNhZztDBB/3v1rkayk5m28KxmupvBYb0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/dineshshetty/Android-InsecureBankv2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/dineshshetty/Android-InsecureBankv2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iHOme/hyNhZztDBB/3v1rkayk5m28KxmupvBYb0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - dineshshetty/Android-InsecureBankv2: Vulnerable Android application for developers and security enthusiasts to learn ab&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vulnerable Android application for developers and security enthusiasts to learn about Android insecurities - GitHub - dineshshetty/Android-InsecureBankv2: Vulnerable Android application for develop...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;금융권 앱을 모델로 하고 있어, 모바일 취약점 진단 입문자(안드로이드 앱 취약점 분석)가 취약점 진단을 학습하기 좋은 앱&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;513&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byLGEd/btrJELEk0AR/slDQi29adEdGolAuJeDB3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byLGEd/btrJELEk0AR/slDQi29adEdGolAuJeDB3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byLGEd/btrJELEk0AR/slDQi29adEdGolAuJeDB3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyLGEd%2FbtrJELEk0AR%2FslDQi29adEdGolAuJeDB3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;513&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;513&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 파일들에 대한 간략한 설명을 하자면 이렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AndroLabServer : 인시큐어뱅크 백엔드 서버&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;InsecureBankv2 : 인시큐어뱅크 안드로이드 어플리케이션 소스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;InsecureBankv2.apk : 인시큐어뱅크 안드로이드 어플리케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Usage Guide.pdf : 유저 가이드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;환경 구성 및 설정(JDK, 안드로이드 스튜디오, 파이썬)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ JDK, 안드로이드 스튜디오, 파이썬 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;소스코드를 이용하기 위하여, &lt;span style=&quot;color: #ee2323;&quot;&gt;안드로이드 어플리케이션 개발 환경&lt;/span&gt; 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- JDK(64bit) 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 설치 시, 모두 디폴트 값(설치 경로 등)으로 진행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. [윈도우 키] - [고급 시스템 설정 보기] - [고급 탭] - [환경변수]&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cv89MZ/btrJCoC7jOG/o92tWBilftszfabIykuQ3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv89MZ/btrJCoC7jOG/o92tWBilftszfabIykuQ3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv89MZ/btrJCoC7jOG/o92tWBilftszfabIykuQ3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv89MZ%2FbtrJCoC7jOG%2Fo92tWBilftszfabIykuQ3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;609&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. [시스템 변수] - [새로만들기] - jdk 설치 경로 입력 후 &quot;확인&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. [시스템 변수] - [path 변수] 클릭 후, &lt;b&gt;%JAVA_HOME%\bin;&lt;/b&gt; 입력 후 cmd에서 &quot;java -version&quot;으로 설정 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8H349/btrJB4rkqYn/9jYPKPYc513RIn8C9mtLzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8H349/btrJB4rkqYn/9jYPKPYc513RIn8C9mtLzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8H349/btrJB4rkqYn/9jYPKPYc513RIn8C9mtLzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8H349%2FbtrJB4rkqYn%2F9jYPKPYc513RIn8C9mtLzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;839&quot; height=&quot;217&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc2w0U/btrJA5kc33u/HfKCe1KJP1JG9XkJ24iKLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc2w0U/btrJA5kc33u/HfKCe1KJP1JG9XkJ24iKLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc2w0U/btrJA5kc33u/HfKCe1KJP1JG9XkJ24iKLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc2w0U%2FbtrJA5kc33u%2FHfKCe1KJP1JG9XkJ24iKLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;672&quot; height=&quot;101&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 안드로이드 스튜디오 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://developer.android.com/studio?hl=ko&quot;&gt;https://developer.android.com/studio?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643939926862&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download Android Studio and SDK tools &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;The official IDE for Android app developers.&quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/studio?hl=ko&quot; data-og-url=&quot;https://developer.android.com/studio&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://developer.android.com/studio?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/studio?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download Android Studio and SDK tools &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The official IDE for Android app developers.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 설치 시, 모두 디폴트 값(설치 경로 등)으로 진행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 스튜디오 설치 완료 후, [setup wizard] - &lt;span style=&quot;color: #ee2323;&quot;&gt;sdk license 모두 Accept&lt;/span&gt;, [Finish] 버튼 클릭 후, 설치 진행(※중요!)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyecbW/btrJCoC7jRi/jPa07KbEBPtMVUOKUyIe70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyecbW/btrJCoC7jRi/jPa07KbEBPtMVUOKUyIe70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyecbW/btrJCoC7jRi/jPa07KbEBPtMVUOKUyIe70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyecbW%2FbtrJCoC7jRi%2FjPa07KbEBPtMVUOKUyIe70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;593&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. [More Actions]&amp;nbsp; - [SDK Manager] 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qmHpe/btrJA5xLXLX/hh5JSDX2VZek6LTS6fXas1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qmHpe/btrJA5xLXLX/hh5JSDX2VZek6LTS6fXas1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qmHpe/btrJA5xLXLX/hh5JSDX2VZek6LTS6fXas1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqmHpe%2FbtrJA5xLXLX%2Fhh5JSDX2VZek6LTS6fXas1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;593&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. Status에서 설치 유무를 확인 가능하며, 테스트 할 안드로이드 버전을 선택 후 [Apply] 클릭 후 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;703&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8ocD7/btrJBmeY2Dx/t1cskuv0j7p15VT3V7gCfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8ocD7/btrJBmeY2Dx/t1cskuv0j7p15VT3V7gCfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8ocD7/btrJBmeY2Dx/t1cskuv0j7p15VT3V7gCfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8ocD7%2FbtrJBmeY2Dx%2Ft1cskuv0j7p15VT3V7gCfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;968&quot; height=&quot;703&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;703&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. [More Actions]&amp;nbsp; - [Virtual Device Manager] 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAUmKv/btrJBKfCwut/uojPPVPUKFhxvKDn32a90k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAUmKv/btrJBKfCwut/uojPPVPUKFhxvKDn32a90k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAUmKv/btrJBKfCwut/uojPPVPUKFhxvKDn32a90k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAUmKv%2FbtrJBKfCwut%2FuojPPVPUKFhxvKDn32a90k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;593&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;6. 좌측 상단 [Create device] 클릭&amp;nbsp; - 카테고리(Phone) [Nexus 5] 클릭 후 이미지 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxZSI7/btrJD3ea6Gl/Km7QxGQR6ROSfYxxpCwgi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxZSI7/btrJD3ea6Gl/Km7QxGQR6ROSfYxxpCwgi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxZSI7/btrJD3ea6Gl/Km7QxGQR6ROSfYxxpCwgi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxZSI7%2FbtrJD3ea6Gl%2FKm7QxGQR6ROSfYxxpCwgi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;794&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;7. AVD Name 변경 후 설정 완료(설정이 잘못되거나, 정상적으로 실행 안된다면, 옵션 변경 필요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pr1vF/btrJB3zbugE/OqtE26JCmpeZzGspibaQ90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pr1vF/btrJB3zbugE/OqtE26JCmpeZzGspibaQ90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pr1vF/btrJB3zbugE/OqtE26JCmpeZzGspibaQ90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpr1vF%2FbtrJB3zbugE%2FOqtE26JCmpeZzGspibaQ90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1001&quot; height=&quot;794&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;8. Actions 에서 재생 버튼을 누르면 디바이스 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbK3Od/btrJB2UzlO7/B1116BkhPLbDtKmKuQ6J8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbK3Od/btrJB2UzlO7/B1116BkhPLbDtKmKuQ6J8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbK3Od/btrJB2UzlO7/B1116BkhPLbDtKmKuQ6J8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbK3Od%2FbtrJB2UzlO7%2FB1116BkhPLbDtKmKuQ6J8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;594&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xH9Fc/btrJAL0I64K/nDo1VSkNImVGEcg5mai1oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xH9Fc/btrJAL0I64K/nDo1VSkNImVGEcg5mai1oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xH9Fc/btrJAL0I64K/nDo1VSkNImVGEcg5mai1oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxH9Fc%2FbtrJAL0I64K%2FnDo1VSkNImVGEcg5mai1oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;399&quot; height=&quot;816&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;9. ADB(Android Debug Bridge) 환경 변수 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ADB는 안드로이드 개발용으로 만들어진 디버그 테스팅 도구이기에, 개발과 취약점 진단에 반드시 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본 설치 경로 : C:\Users\&lt;span style=&quot;color: #ee2323;&quot;&gt;사용자&lt;/span&gt;\AppData\Local\Android\Sdk\platform-tools&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;[윈도우 키] - [고급 시스템 설정 보기] - [고급 탭] - [환경변수] - [시스템 변수] - [path 변수] 클릭 후, 위의 설치 경로 입력 후 cmd에서 결과 확인(커맨드라인에 &quot;adb version&quot; 입력)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSLgEs/btrJCp24KLn/hHMZF2K7Mj3qN6pIWKgTjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSLgEs/btrJCp24KLn/hHMZF2K7Mj3qN6pIWKgTjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSLgEs/btrJCp24KLn/hHMZF2K7Mj3qN6pIWKgTjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSLgEs%2FbtrJCp24KLn%2FhHMZF2K7Mj3qN6pIWKgTjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;664&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp9Qxu/btrJB3stydM/Z8YHM0XScbis3g7k3Re801/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp9Qxu/btrJB3stydM/Z8YHM0XScbis3g7k3Re801/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp9Qxu/btrJB3stydM/Z8YHM0XScbis3g7k3Re801/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp9Qxu%2FbtrJB3stydM%2FZ8YHM0XScbis3g7k3Re801%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;98&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 파이썬(python) 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.python.org/downloads/release/python-2717/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.python.org/downloads/release/python-2717/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1643958720927&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Python Release Python 2.7.17&quot; data-og-description=&quot;The official home of the Python Programming Language&quot; data-og-host=&quot;www.python.org&quot; data-og-source-url=&quot;https://www.python.org/downloads/release/python-2717/&quot; data-og-url=&quot;https://www.python.org/downloads/release/python-2717/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvLS28/hyNhZzEd94/C4NK4Ds7jir8GPYIiFzY50/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://www.python.org/downloads/release/python-2717/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.python.org/downloads/release/python-2717/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvLS28/hyNhZzEd94/C4NK4Ds7jir8GPYIiFzY50/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Python Release Python 2.7.17&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The official home of the Python Programming Language&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.python.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;※주의사항&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파이썬 구버전이나, 위에 있는 버전으로 진행해야 오류 없이 빠르게 진행 가능함!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGvE81/btrJANc3gtE/AqkWOxKF5zMqZXkTesF021/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGvE81/btrJANc3gtE/AqkWOxKF5zMqZXkTesF021/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGvE81/btrJANc3gtE/AqkWOxKF5zMqZXkTesF021/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGvE81%2FbtrJANc3gtE%2FAqkWOxKF5zMqZXkTesF021%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;618&quot; height=&quot;533&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;디폴트로 설치 진행했다면, 파이썬 설치 기본경로는 &lt;b&gt;&quot;C:\Python27&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 파이썬을 위에 있는 버전으로 설치 후, 서버 구동을 위한 라이브러리를 설치함(목록은 하기와 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- simplejson&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- flask&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- sqlalchemy&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- cherrypy&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- web.py&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 위에 있는 라이브러리를 설치하기 위해 easy_install을 이용해야하는데, easy_install은 &lt;b&gt;&quot;C:\Python27\Scripts&quot;&amp;nbsp;&lt;/b&gt;해당 경로에 존재함.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;31&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W1tt7/btrJB4x7p2H/aDDyPFsamnn0pmiHJxM5LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W1tt7/btrJB4x7p2H/aDDyPFsamnn0pmiHJxM5LK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W1tt7/btrJB4x7p2H/aDDyPFsamnn0pmiHJxM5LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW1tt7%2FbtrJB4x7p2H%2FaDDyPFsamnn0pmiHJxM5LK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;31&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;31&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;▲위 명령어 입력하여 설치 진행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YRTlh/btrJCpWmgHC/6UllFg1fAw4bnbkWRWGTcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YRTlh/btrJCpWmgHC/6UllFg1fAw4bnbkWRWGTcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YRTlh/btrJCpWmgHC/6UllFg1fAw4bnbkWRWGTcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYRTlh%2FbtrJCpWmgHC%2F6UllFg1fAw4bnbkWRWGTcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;54&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;▲정상적으로 설치되면 다음과 같은 메시지 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;※&lt;span style=&quot;color: #ee2323;&quot;&gt;easy_install 명령어를 이용하여 설치 불가 및 에러 발생 시&lt;/span&gt;, 다음과 같은 방법 사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;1) 환경변수 설정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;[윈도우 키] - [고급 시스템 설정 보기] - [고급 탭] - [환경변수] - [시스템 변수] - [path 변수] 클릭 후, &lt;b&gt;C:\Python27\Scripts\&lt;/b&gt; 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/di7620/btrJA3tdog7/nHLSzGBeXVXbnzn90bIjJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/di7620/btrJA3tdog7/nHLSzGBeXVXbnzn90bIjJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/di7620/btrJA3tdog7/nHLSzGBeXVXbnzn90bIjJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdi7620%2FbtrJA3tdog7%2FnHLSzGBeXVXbnzn90bIjJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;532&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;2) 관리자 권한으로 명령 프롬프트(CMD) 실행 후, &lt;b&gt;pip install --uprade pip&lt;/b&gt; 입력&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;23&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwMZCn/btrJBJuekSV/aLIWfNgJurwJf4yfFxoDh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwMZCn/btrJBJuekSV/aLIWfNgJurwJf4yfFxoDh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwMZCn/btrJBJuekSV/aLIWfNgJurwJf4yfFxoDh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwMZCn%2FbtrJBJuekSV%2FaLIWfNgJurwJf4yfFxoDh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;23&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;23&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;3) 아래 명령어 차례대로 입력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- pip install flask&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- pip install sqlalchemy&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- pip install simplejson&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- pip install cherrypy&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- pip install web.py&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;(아래 화면은 명령어 입력 시, 정상 설치 예시 화면)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJtvzo/btrJAMrKlmp/YvKjSxMD2K63pd3Qq4Zjek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJtvzo/btrJAMrKlmp/YvKjSxMD2K63pd3Qq4Zjek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJtvzo/btrJAMrKlmp/YvKjSxMD2K63pd3Qq4Zjek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJtvzo%2FbtrJAMrKlmp%2FYvKjSxMD2K63pd3Qq4Zjek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;678&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 다운로드 받은 인시큐어뱅크 서버 설치 경로에 AndroLabServer 디렉터리에서&lt;b&gt; app.py&lt;/b&gt; 실행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;33&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xtlq7/btrJBKzUZnR/SyGdJzgQESNVX9YpV4rH3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xtlq7/btrJBKzUZnR/SyGdJzgQESNVX9YpV4rH3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xtlq7/btrJBKzUZnR/SyGdJzgQESNVX9YpV4rH3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxtlq7%2FbtrJBKzUZnR%2FSyGdJzgQESNVX9YpV4rH3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;34&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;33&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;▲ 서버 정상 작동 시, 위와 같은 문구 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인시큐어뱅크 어플리케이션 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 어플리케이션 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;안드로이드 스튜디오에서 가상 장치 설정과 인큐어뱅크 백엔드 서버를 정상적으로 구동시켰으므로, 가상장치에 어플리케이션 설치 진행(인시큐어뱅크 어플리케이션은 다운받은 폴더 내에 포함되어 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 인시큐어뱅크 폴더로 이동 후, 명령어 입력 &lt;b&gt;adb install InsecureBankv2.apk&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LuVdi/btrJB30iOvx/FhhIwDK3MKvbNAASr8h85k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LuVdi/btrJB30iOvx/FhhIwDK3MKvbNAASr8h85k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LuVdi/btrJB30iOvx/FhhIwDK3MKvbNAASr8h85k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLuVdi%2FbtrJB30iOvx%2FFhhIwDK3MKvbNAASr8h85k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;82&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;82&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 안드로이드 가상 장치(AVD) 앱 메뉴에서 설치된 인시큐어뱅크 어플 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpCwa7/btrJB3styfz/VrxiGYkfir2uOxJmTgZGyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpCwa7/btrJB3styfz/VrxiGYkfir2uOxJmTgZGyK/img.png&quot; data-alt=&quot;AVD 내 어플 설치 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpCwa7/btrJB3styfz/VrxiGYkfir2uOxJmTgZGyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpCwa7%2FbtrJB3styfz%2FVrxiGYkfir2uOxJmTgZGyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;853&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AVD 내 어플 설치 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9sxZj/btrJA4MqvRx/9zjNlGG6tSlXmN6dgDmuGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9sxZj/btrJA4MqvRx/9zjNlGG6tSlXmN6dgDmuGK/img.png&quot; data-alt=&quot;인시큐어뱅크 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9sxZj/btrJA4MqvRx/9zjNlGG6tSlXmN6dgDmuGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9sxZj%2FbtrJA4MqvRx%2F9zjNlGG6tSlXmN6dgDmuGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;853&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인시큐어뱅크 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 서버 IP 주소(Server IP)는 우측 메뉴 &lt;b&gt;&quot;Preferences&quot;&lt;/b&gt; 에서 확인 및 변경 가능. 위의 과정대로 설치했다면 기본 포트 번호는 8888로 설정되어 있음. &lt;b&gt;&quot;Submit&quot;&lt;/b&gt; 버튼 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tEeuY/btrJB4rkrnm/y0ZQF7pCs4HPmjcrovfD8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tEeuY/btrJB4rkrnm/y0ZQF7pCs4HPmjcrovfD8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tEeuY/btrJB4rkrnm/y0ZQF7pCs4HPmjcrovfD8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtEeuY%2FbtrJB4rkrnm%2Fy0ZQF7pCs4HPmjcrovfD8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;853&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc5GMu/btrJCopzOb0/c4sC5dGRunSbprHKMiKpHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc5GMu/btrJCopzOb0/c4sC5dGRunSbprHKMiKpHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc5GMu/btrJCopzOb0/c4sC5dGRunSbprHKMiKpHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc5GMu%2FbtrJCopzOb0%2Fc4sC5dGRunSbprHKMiKpHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;853&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 인시큐어뱅크 계정 정보&lt;b&gt;(ID : dinesh, PW : Dinesh@123$ / ID : jack, PW : Jack@123$)&lt;/b&gt;로 로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또는, &lt;b&gt;&quot;Autofill Credentials&quot;&lt;/b&gt; 버튼을 클릭하면 자동으로 계정 정보가 입력됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0iLCQ/btrJANqy0Du/pYgkErk0u4kwyj4TMyRkTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0iLCQ/btrJANqy0Du/pYgkErk0u4kwyj4TMyRkTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0iLCQ/btrJANqy0Du/pYgkErk0u4kwyj4TMyRkTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0iLCQ%2FbtrJANqy0Du%2FpYgkErk0u4kwyj4TMyRkTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;869&quot; height=&quot;712&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이것으로 인시큐어뱅크 설치 과정을 마친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/안드로이드 취약점 진단</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/59</guid>
      <comments>https://fathersit.tistory.com/59#entry59comment</comments>
      <pubDate>Sat, 13 Aug 2022 16:36:57 +0900</pubDate>
    </item>
    <item>
      <title>안드로이드 모바일 어플리케이션 디컴파일(간단한 툴 사용법)</title>
      <link>https://fathersit.tistory.com/54</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;모바일 어플리케이션 디컴파일하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 디컴파일 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Android&amp;nbsp;Manifest&lt;/b&gt; &lt;br /&gt;앱에 필수로 들어가야되며, &lt;span style=&quot;color: #ee2323;&quot;&gt;앱에&amp;nbsp;대한&amp;nbsp;필수적인&amp;nbsp;정보&lt;/span&gt;를 담고 있음. 특히, 앱의 패키지 이름과 사용되는 컴포넌트 및 권한 등이 전부 담겨 있음 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;DEX&lt;/b&gt; &lt;br /&gt;안드로이드&amp;nbsp;환경에서의&amp;nbsp;실행&amp;nbsp;파일 &lt;br /&gt;Java&amp;nbsp;코드로&amp;nbsp;작성된&amp;nbsp;컴파일된&amp;nbsp;class&amp;nbsp;파일을&amp;nbsp;DX&amp;nbsp;도구를&amp;nbsp;사용해&amp;nbsp;변환시킨&amp;nbsp;파일 &lt;br /&gt;&amp;nbsp;-&amp;nbsp;Java&amp;nbsp;바이트&amp;nbsp;코드가&amp;nbsp;달빅&amp;nbsp;다이트&amp;nbsp;코드로&amp;nbsp;변환 &lt;br /&gt;달빅 가상머신에서 구동&lt;br /&gt;&amp;nbsp;-&amp;nbsp;실행되는&amp;nbsp;앱마다&amp;nbsp;가상머신을&amp;nbsp;생성해&amp;nbsp;구동시킴 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;SMALI&lt;/b&gt; &lt;br /&gt;DEX 바이너리를 사람이 읽을 수 있도록 표현. DEX를 디코딩 작업으로 추출할 수 있음.&lt;br /&gt;Smali&amp;nbsp;파일의&amp;nbsp;코드를&amp;nbsp;분석해&amp;nbsp;프로그램의&amp;nbsp;실행&amp;nbsp;원리&amp;nbsp;파악&amp;nbsp;가능 &lt;br /&gt;Smali&amp;nbsp;코드를&amp;nbsp;읽고,&amp;nbsp;수정&amp;nbsp;후&amp;nbsp;재컴파일해서&amp;nbsp;프로그램&amp;nbsp;수정&amp;nbsp;가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(조작하면 동적제어가 가능함)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 2px 12px; border-bottom-style: solid; border-bottom-color: #000000; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;apk 디컴파일 툴(apktool, dex2jar, jd-gui, BytecodeViewer)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안드로이드 어플리케이션 디컴파일하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;소스코드를 가지고 있지 않은 상태에서는 디컴파일을 통해 어플리케이션을 분석해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;어플리케이션 변조 과정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- APK 획득 -&amp;gt; 디컴파일 -&amp;gt; 코드변조 -&amp;gt; 컴파일 -&amp;gt; 사이닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;■ &lt;/b&gt;apktool 사용법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;apk 파일로 압축되어 있는 resource.arsc, classes.dex XML 파일들을 디버깅 형태로 변환시켜주는 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://ibotpeaches.github.io/Apktool/install/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ibotpeaches.github.io/Apktool/install/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644811696945&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apktool - How to Install&quot; data-og-description=&quot;Install Instructions Quick Check Is at least Java 1.8 installed? Does executing java -version on command line / command prompt return 1.8 or greater? If not, please install Java 8+ and make it the default. (Java 7 will also work at this time) Windows: Down&quot; data-og-host=&quot;ibotpeaches.github.io&quot; data-og-source-url=&quot;https://ibotpeaches.github.io/Apktool/install/&quot; data-og-url=&quot;https://ibotpeaches.github.io/Apktool/install/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ibotpeaches.github.io/Apktool/install/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ibotpeaches.github.io/Apktool/install/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apktool - How to Install&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Install Instructions Quick Check Is at least Java 1.8 installed? Does executing java -version on command line / command prompt return 1.8 or greater? If not, please install Java 8+ and make it the default. (Java 7 will also work at this time) Windows: Down&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ibotpeaches.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;설치 파일 및 설치법은 위 주소로 접속하여 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3OrD3/btrJwYw75z5/TLRvJ78QwDqNKitxPcPlB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3OrD3/btrJwYw75z5/TLRvJ78QwDqNKitxPcPlB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3OrD3/btrJwYw75z5/TLRvJ78QwDqNKitxPcPlB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3OrD3%2FbtrJwYw75z5%2FTLRvJ78QwDqNKitxPcPlB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;916&quot; height=&quot;242&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;옵션은 d 를 사용하여 디컴파일 명령어&lt;b&gt;(apktool d 파일경로)&lt;/b&gt; 입력&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;C:\Users\CDM\app-release 폴더에서 결과값 아래와 같이 확인&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nQmaE/btrJvSqCbO2/hp0kMRx5W7DpFlkyiQsLd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nQmaE/btrJvSqCbO2/hp0kMRx5W7DpFlkyiQsLd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nQmaE/btrJvSqCbO2/hp0kMRx5W7DpFlkyiQsLd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnQmaE%2FbtrJvSqCbO2%2Fhp0kMRx5W7DpFlkyiQsLd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;228&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;※smali 파일은 조작하면 동작제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;■ &lt;/b&gt;dex2jar 사용법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;apk 파일이나 apk 파일에 포함된 classes.dex 파일을 자바 클래스 파일로 변환시켜주는 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://sourceforge.net/projects/dex2jar/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sourceforge.net/projects/dex2jar/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644812413699&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;product&quot; data-og-title=&quot;dex2jar&quot; data-og-description=&quot;Download dex2jar for free. Tools to work with android .dex and java .class files. Mirrors: * https://bitbucket.org/pxb1988/dex2jar * https://github.com/pxb1988/dex2jar dex2jar contains following compment * dex-reader is designed to read the Dalvik Executab&quot; data-og-host=&quot;sourceforge.net&quot; data-og-source-url=&quot;https://sourceforge.net/projects/dex2jar/&quot; data-og-url=&quot;https://sourceforge.net/projects/dex2jar/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sourceforge.net/projects/dex2jar/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sourceforge.net/projects/dex2jar/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;dex2jar&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Download dex2jar for free. Tools to work with android .dex and java .class files. Mirrors: * https://bitbucket.org/pxb1988/dex2jar * https://github.com/pxb1988/dex2jar dex2jar contains following compment * dex-reader is designed to read the Dalvik Executab&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sourceforge.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;763&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pb5wS/btrJuSdPG8s/KbkZpW2pvBXiAIkOqWKWfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pb5wS/btrJuSdPG8s/KbkZpW2pvBXiAIkOqWKWfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pb5wS/btrJuSdPG8s/KbkZpW2pvBXiAIkOqWKWfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpb5wS%2FbtrJuSdPG8s%2FKbkZpW2pvBXiAIkOqWKWfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;763&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;763&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;dex2jar를 이용할 땐, 디컴파일할 파일을 다운로드 받은 dex2jar 폴더 내로 이동시켜주어야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJeFMA/btrJrQ8T7Ie/ND5Xt4FmXdISYfCdCaKoJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJeFMA/btrJrQ8T7Ie/ND5Xt4FmXdISYfCdCaKoJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJeFMA/btrJrQ8T7Ie/ND5Xt4FmXdISYfCdCaKoJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJeFMA%2FbtrJrQ8T7Ie%2FND5Xt4FmXdISYfCdCaKoJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;49&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mn7a3/btrJvQzBkA3/7KElHjk0jZ5ockLEgbr0Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mn7a3/btrJvQzBkA3/7KElHjk0jZ5ockLEgbr0Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mn7a3/btrJvQzBkA3/7KElHjk0jZ5ockLEgbr0Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmn7a3%2FbtrJvQzBkA3%2F7KElHjk0jZ5ockLEgbr0Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;267&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행파일을 .jar 확장자를 가진 파일로 변환 및 파일 생성 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(명령어 : d2j-dex2jar.bat InsecureBankv2.apk)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;■ &lt;/b&gt;&lt;/b&gt;jd-gui 사용법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;jar 파일을 사용자가 읽을 수 있는 형태로 디컴파일하기 위하여 사용하며, dex2jar을 이용하여 생성된 jar 파일을 불러오면 자동으로 디컴파일 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;http://java-decompiler.github.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://java-decompiler.github.io/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644814422132&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Java Decompiler&quot; data-og-description=&quot;The &amp;ldquo;Java Decompiler project&amp;rdquo; aims to develop tools in order to decompile and analyze Java 5 &amp;ldquo;byte code&amp;rdquo; and the later versions. JD-GUI is a standalone graphical utility that displays Java source codes of &amp;ldquo;.class&amp;rdquo; files. You can browse the reco&quot; data-og-host=&quot;java-decompiler.github.io&quot; data-og-source-url=&quot;http://java-decompiler.github.io/&quot; data-og-url=&quot;http://java-decompiler.github.io/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://java-decompiler.github.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://java-decompiler.github.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Java Decompiler&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The &amp;ldquo;Java Decompiler project&amp;rdquo; aims to develop tools in order to decompile and analyze Java 5 &amp;ldquo;byte code&amp;rdquo; and the later versions. JD-GUI is a standalone graphical utility that displays Java source codes of &amp;ldquo;.class&amp;rdquo; files. You can browse the reco&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;java-decompiler.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcZuXH/btrJypVw7pq/Pg6GbdmpiTkyg9VfTzhbhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcZuXH/btrJypVw7pq/Pg6GbdmpiTkyg9VfTzhbhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcZuXH/btrJypVw7pq/Pg6GbdmpiTkyg9VfTzhbhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcZuXH%2FbtrJypVw7pq%2FPg6GbdmpiTkyg9VfTzhbhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;762&quot; height=&quot;505&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;윈도우 버전의 압축파일을 다운로드 받은 후, 압축해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAWmAB/btrJu5cWHXv/MZs8WGEWF0ydRCNLX7KMbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAWmAB/btrJu5cWHXv/MZs8WGEWF0ydRCNLX7KMbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAWmAB/btrJu5cWHXv/MZs8WGEWF0ydRCNLX7KMbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAWmAB%2FbtrJu5cWHXv%2FMZs8WGEWF0ydRCNLX7KMbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;168&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CeV9i/btrJvkHHbVy/hXI4EzKg7kvMb5wyGDyLN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CeV9i/btrJvkHHbVy/hXI4EzKg7kvMb5wyGDyLN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CeV9i/btrJvkHHbVy/hXI4EzKg7kvMb5wyGDyLN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCeV9i%2FbtrJvkHHbVy%2FhXI4EzKg7kvMb5wyGDyLN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;969&quot; height=&quot;381&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;dex2jar을 이용하여 생성된 jar 파일을 jd-gui로 불러오면 자동으로 디컴파일 및 결과 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;BytecodeViewer 사용법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;BytecodeViewer는 안드로이드 뿐만 아니라, 자바, DEX, jars 파일 등과 같은 소스코드 리버싱 분석 도구. 윈도우 환경에서도 완벽하게 동작하며, 안드로이드 APK 파일을 디컴파일하여 바이트코드 형태와 클래스 파일을 자바 파일로 변환한 후 소스파일로 복원하여 함께 보여줌. 앞서 소개한 도구들의 기능을 모두 합한 것과 같아서 효율적인 도구이며, 분석 속도가 매우 빠름.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://github.com/Konloch/bytecode-viewer/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/Konloch/bytecode-viewer/releases&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644816575263&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Releases &amp;middot; Konloch/bytecode-viewer&quot; data-og-description=&quot;A Java 8+ Jar &amp;amp; Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger &amp;amp; More) - Konloch/bytecode-viewer&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Konloch/bytecode-viewer/releases&quot; data-og-url=&quot;https://github.com/Konloch/bytecode-viewer/releases&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzfweA/hyNpi6yadd/mmxG8umuedO86mG7OzGKE1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Konloch/bytecode-viewer/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Konloch/bytecode-viewer/releases&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzfweA/hyNpi6yadd/mmxG8umuedO86mG7OzGKE1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Releases &amp;middot; Konloch/bytecode-viewer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A Java 8+ Jar &amp;amp; Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger &amp;amp; More) - Konloch/bytecode-viewer&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;jar 파일을 다운로드 후, 설치경로에서 명령어(&lt;b&gt;java -jar Bytecode-Viewer-2.11..0 jar&lt;/b&gt;) 입력하면 bytecodeviewer가 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eaI0Kf/btrJqqCrfjB/JNPyIqcgkQZi9wXGZucAW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eaI0Kf/btrJqqCrfjB/JNPyIqcgkQZi9wXGZucAW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eaI0Kf/btrJqqCrfjB/JNPyIqcgkQZi9wXGZucAW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeaI0Kf%2FbtrJqqCrfjB%2FJNPyIqcgkQZi9wXGZucAW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;34&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Vlmx/btrJvbqikCm/mHIinBftbvcOjiDyfzikBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Vlmx/btrJvbqikCm/mHIinBftbvcOjiDyfzikBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Vlmx/btrJvbqikCm/mHIinBftbvcOjiDyfzikBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Vlmx%2FbtrJvbqikCm%2FmHIinBftbvcOjiDyfzikBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;170&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;1032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0fDku/btrJvbRlUiI/FT0CKdvxv82rLTmIXuMFH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0fDku/btrJvbRlUiI/FT0CKdvxv82rLTmIXuMFH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0fDku/btrJvbRlUiI/FT0CKdvxv82rLTmIXuMFH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0fDku%2FbtrJvbRlUiI%2FFT0CKdvxv82rLTmIXuMFH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;432&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;1032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;분석하고자 하는 파일을 드래그 시키거나, 오픈하면 아래와 같이 결과가 출력(좌측 - 소스코드, 우측 - 바이트코드)되는데 해석된 2개의 코드를 동시에 볼 수 있다는 점에서 매력적이며, 다양한 플러그인을 활용하여 분석이 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;1025&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9BCHa/btrJvcJu6OU/wrQ8vZfqK9Ri2iTvTfwQEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9BCHa/btrJvcJu6OU/wrQ8vZfqK9Ri2iTvTfwQEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9BCHa/btrJvcJu6OU/wrQ8vZfqK9Ri2iTvTfwQEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9BCHa%2FbtrJvcJu6OU%2FwrQ8vZfqK9Ri2iTvTfwQEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1921&quot; height=&quot;1025&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;1025&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/안드로이드 취약점 진단</category>
      <category>디컴파일</category>
      <category>취약점 진단</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/54</guid>
      <comments>https://fathersit.tistory.com/54#entry54comment</comments>
      <pubDate>Fri, 12 Aug 2022 02:42:00 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 취약한 암호화 알고리즘 사용</title>
      <link>https://fathersit.tistory.com/40</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rbl0I/btrJqlT7CIJ/8jzdNst5nuCLnVx0RgbaeK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rbl0I/btrJqlT7CIJ/8jzdNst5nuCLnVx0RgbaeK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rbl0I/btrJqlT7CIJ/8jzdNst5nuCLnVx0RgbaeK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frbl0I%2FbtrJqlT7CIJ%2F8jzdNst5nuCLnVx0RgbaeK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취약한 암호화 알고리즘 사용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SW 개발자들은 환경설정 파일에 저장된 패스워드를 보호하기 위하여 간단한 인코딩 함수를 이용 하여 패스워드를 감추는 방법을&amp;nbsp;사용하기도&amp;nbsp;한다.&amp;nbsp;그렇지만&amp;nbsp;base64와&amp;nbsp;같은&amp;nbsp;지나치게&amp;nbsp;간단한&amp;nbsp;인코딩&amp;nbsp;함수로는&amp;nbsp;패스워드를&amp;nbsp;제대로&amp;nbsp;보호할&amp;nbsp;수&amp;nbsp;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;정보보호 측면에서 취약하거나 위험한 암호화 알고리즘을 사용해서는 안 된다. 표준화되지 않은 암호화 알고리즘을 사용하는 것은 공격자가 알고리즘을 분석하여 무력화시킬 수 있는 가능성을 높일 수도 있다. 몇몇 오래된 암호화 알고리즘의 경우는 컴퓨터의 성능이 향상됨에 따라 취약해지기도 해서, 예전에는 해독하는데 몇 십 억년이 걸릴 것이라고 예상되던 알고리즘이 며칠이나 몇 시간 내에 해독되기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RC2 (ARC2), RC4 (ARC4), RC5, RC6, MD4, MD5, SHA1, DES 알고리즘이 여기에&amp;nbsp;해당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python 2에서는 PyCrypto를 사용하였지만 Python 3에서는 PyCryto를 개선한 PyCryptodomes를 사용하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자신만의 암호화 알고리즘을 개발하는 것은 위험하며, 학계 및 업계에서 이미 검증된 표준화된 알고리즘을 사용한다. 기존에 취약하다고 알려진 DES, RC5등의 암호알고리즘을 대신하여, 3DES, AES, SEED 등의 안전한 암호 알고리즘으로 대체하여 사용한다. 또한, 업무관련 내용, 개인정보 등에 대한 암호 알고리즘 적용 시, 암호모듈시험기에서 안전성을 확인한 검증필 암호모듈을&amp;nbsp;사용해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 취약한 DES 알고리즘으로 암호화하고 있다. DES 이외에 3DES, Blowfish, ARC2, ARC4 등의 취약한 알고리즘을&amp;nbsp;사용하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;base64 &lt;br /&gt;from&amp;nbsp;Crypto.Cipher&amp;nbsp;import&amp;nbsp;DES&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_enc_text(plain_text,&amp;nbsp;key): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;취약함&amp;nbsp;암호와&amp;nbsp;알고리즘인&amp;nbsp;DES를&amp;nbsp;사용하여&amp;nbsp;안전하지&amp;nbsp;않음 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;cipher_des&amp;nbsp;=&amp;nbsp;DES.new(key,&amp;nbsp;DES.MODE_ECB)&lt;/span&gt; &lt;br /&gt;encrypted_data&amp;nbsp;=&amp;nbsp;base64.b64encode(cipher_des.encrypt(plain_text))&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;encrypted_data.decode('ASCII')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;pycrypto 라이브러리는 python 3.x버전 환경에서 사용 시 동작을 하지 않는 경우가 발생하며, 더 이상 유지관리 되지 않으므로 pycrypto를 개선한 pycryptodome를 사용한다. 취약한 DES 알고리즘 대신 안전한 AES 암호화 알고리즘을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록 암호화에서 운영모드를 ECB(Electronic Code Block) 모드를 사용할 경우 한 개의 블록만 해독되면 나머지 블록도 해독이 되는 단점이 있다. CBC(Cipher Block Chaining) 모드는 평문의 각 블록이 XOR연산을 통해 이전 암호문과 연산이 되기 때문에&amp;nbsp;같은&amp;nbsp;평문이라도&amp;nbsp;암호문이&amp;nbsp;서로&amp;nbsp;다르다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이러한&amp;nbsp;특성으로&amp;nbsp;보안성이&amp;nbsp;ECB&amp;nbsp;모드보다&amp;nbsp;높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;base64 &lt;br /&gt;from&amp;nbsp;Crypto.Cipher&amp;nbsp;import&amp;nbsp;AES&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_enc_text(plain_text,&amp;nbsp;key,&amp;nbsp;iv): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;안전한&amp;nbsp;알고리즘인&amp;nbsp;AES&amp;nbsp;를&amp;nbsp;사용하여&amp;nbsp;안전함. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;cipher_aes&amp;nbsp;=&amp;nbsp;AES.new(key,&amp;nbsp;AES.MODE_CBC,&amp;nbsp;iv) &lt;/span&gt;&lt;br /&gt;encrypted_data&amp;nbsp;=&amp;nbsp;base64.b64encode(cipher_aes.encrypt(plain_text))&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;encrypted_data.decode('ASCII')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음&amp;nbsp;예제는&amp;nbsp;취약한&amp;nbsp;MD5&amp;nbsp;해쉬함수를&amp;nbsp;사용하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;fimport&amp;nbsp;hashlib&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;make_md5(plain_text): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;취약한&amp;nbsp;md5&amp;nbsp;해쉬함수&amp;nbsp;사용 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;hash_text&amp;nbsp;=&amp;nbsp;hashlib.md5(plain_text.encode('utf-8')).hexdigest()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;hash_text&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래&amp;nbsp;코드처럼&amp;nbsp;안전하다고&amp;nbsp;알려진&amp;nbsp;sha-256&amp;nbsp;해쉬함수&amp;nbsp;등을&amp;nbsp;적용해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;hashlib&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;make_sha256(plain_text): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;안전한&amp;nbsp;sha-256&amp;nbsp;해쉬함수&amp;nbsp;사용 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;hash_text&amp;nbsp;=&amp;nbsp;hashlib.sha256(plain_text.encode('utf-8')).hexdigest()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;hash_text&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/40</guid>
      <comments>https://fathersit.tistory.com/40#entry40comment</comments>
      <pubDate>Wed, 10 Aug 2022 23:23:14 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 중요한 자원에 대한 잘못된 권한 설정</title>
      <link>https://fathersit.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQ6tj/btrJsP7MaR3/8wkBk5Beiw3uMEBHUfBjM1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQ6tj/btrJsP7MaR3/8wkBk5Beiw3uMEBHUfBjM1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQ6tj/btrJsP7MaR3/8wkBk5Beiw3uMEBHUfBjM1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQ6tj%2FbtrJsP7MaR3%2F8wkBk5Beiw3uMEBHUfBjM1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;중요한 자원에 대한 잘못된 권한 설정(시큐어코딩 가이드)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응용프로그램이 중요한 보안관련 자원에 대하여 읽기 또는 수정하기 권한을 의도하지 않게 허가할 경우, 권한을 갖지 않은 사용자가 해당 자원을 사용하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python의&amp;nbsp;os.fchmod,&amp;nbsp;os.chmod&amp;nbsp;등의&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;파일&amp;nbsp;생성&amp;nbsp;및&amp;nbsp;읽기&amp;nbsp;모드에서&amp;nbsp;권한을&amp;nbsp;설정&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;설정파일, 실행파일, 라이브러리 등은 SW 관리자에 의해서만 읽고 쓰기가 가능하도록 설정하고 설정 파일과 같이 중요한 자원을&amp;nbsp;사용하는&amp;nbsp;경우,&amp;nbsp;허가&amp;nbsp;받지&amp;nbsp;않은&amp;nbsp;사용자가&amp;nbsp;중요한&amp;nbsp;자원에&amp;nbsp;접근&amp;nbsp;가능&amp;nbsp;한지&amp;nbsp;검사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음&amp;nbsp;예제는&amp;nbsp;/root/system_config&amp;nbsp;파일에&amp;nbsp;대해서&amp;nbsp;모든&amp;nbsp;사용자가&amp;nbsp;읽기,&amp;nbsp;쓰기,&amp;nbsp;실행&amp;nbsp;권한을&amp;nbsp;가지게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;def&amp;nbsp;write_file(): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#모든&amp;nbsp;사용자가&amp;nbsp;읽기,&amp;nbsp;쓰기,&amp;nbsp;실행&amp;nbsp;권한을&amp;nbsp;가지게&amp;nbsp;됨. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;os.chmod('/root/system_config',&amp;nbsp;0o777)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;open(&quot;/root/system_config&quot;,&amp;nbsp;'w')&amp;nbsp;as&amp;nbsp;f: &lt;br /&gt;f.write(&quot;your&amp;nbsp;config&amp;nbsp;is&amp;nbsp;broken&quot;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파일에 대해서는 최소권한을 할당해야 한다. 즉 해당 파일의 소유자에게만 읽기 권한만 부여하고 쓰기 권한이 필요한 경우에만&amp;nbsp;쓰기&amp;nbsp;권한을&amp;nbsp;부여한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;def&amp;nbsp;write_file(): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#소유자&amp;nbsp;외에는&amp;nbsp;아무런&amp;nbsp;권한을&amp;nbsp;주지&amp;nbsp;않음. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;os.chmod('/root/system_config',&amp;nbsp;0o700)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;open(&quot;/root/system_config&quot;,&amp;nbsp;&amp;lsquo;'w')&amp;nbsp;as&amp;nbsp;f: &lt;br /&gt;f.write(&quot;your&amp;nbsp;config&amp;nbsp;is&amp;nbsp;broken&quot;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/39</guid>
      <comments>https://fathersit.tistory.com/39#entry39comment</comments>
      <pubDate>Wed, 10 Aug 2022 22:21:44 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 적절한 인증 없는 중요 기능 허용</title>
      <link>https://fathersit.tistory.com/38</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccwUVS/btrJm8V3alu/QvbjtuToamGaG3eaw9jLxk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccwUVS/btrJm8V3alu/QvbjtuToamGaG3eaw9jLxk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccwUVS/btrJm8V3alu/QvbjtuToamGaG3eaw9jLxk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccwUVS%2FbtrJm8V3alu%2FQvbjtuToamGaG3eaw9jLxk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;적절한 인증 없는 중요 기능 허용(시큐어코딩)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;파이썬의 Django 프레임워크에서 django.contrib.auth 앱을 통하여 기본적인 인증 로그인 및 로그아웃 기능을 제공하고 있으며&amp;nbsp;DRF(Django&amp;nbsp;REST&amp;nbsp;Framework)에서는&amp;nbsp;토큰&amp;nbsp;및&amp;nbsp;세션&amp;nbsp;인증을&amp;nbsp;제공하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;클라이언트의&amp;nbsp;보안검사를&amp;nbsp;우회하여&amp;nbsp;서버에&amp;nbsp;접근하지&amp;nbsp;못하도록&amp;nbsp;설계하고&amp;nbsp;중요한&amp;nbsp;정보가&amp;nbsp;있는&amp;nbsp;페이지는&amp;nbsp;재&amp;nbsp;인증을&amp;nbsp;적용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;또한 안전하다고 검증된 라이브러리나 프레임워크 (Django authentication system, Flask-Login 등)를 사용하는 것이 안전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드 수정 시 수정을 요청한 패스워드와 DB에 저장된 사용자 패스워드 일치 여부를 확인하지 않고 처리하고 있으며 패스워드의&amp;nbsp;재확인&amp;nbsp;절차도&amp;nbsp;생략되어&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;re&amp;nbsp;import&amp;nbsp;escape &lt;br /&gt;import&amp;nbsp;hashlib&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;change_password(request): &lt;br /&gt;new_pwd&amp;nbsp;=&amp;nbsp;request.POST.get('new_password','')&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#로그인한&amp;nbsp;사용자정보 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;user&amp;nbsp;=&amp;nbsp;'%s'&amp;nbsp;%&amp;nbsp;escape(request.session['userid'])&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#현재&amp;nbsp;password와&amp;nbsp;일치여부를&amp;nbsp;확인하지&amp;nbsp;않고&amp;nbsp;수정함&lt;/span&gt; &lt;br /&gt;sha&amp;nbsp;=&amp;nbsp;hashlib.sha256(new_pwd.encode()) &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;update_password_from_db(user,&amp;nbsp;sha.hexdigest())&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DB에 저장된 사용자 패스워드와 변경 요청한 패스워드의 일치 여부를 확인하거나 변경 요청한 패스워드와 재확인 패스워드가&amp;nbsp;일치하는지&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;DB의&amp;nbsp;패스워드를&amp;nbsp;수정하도록&amp;nbsp;하여&amp;nbsp;안전하게&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;re&amp;nbsp;import&amp;nbsp;escape &lt;br /&gt;import&amp;nbsp;hashlib&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;login_required&amp;nbsp;decorator를&amp;nbsp;사용하여&amp;nbsp;login된&amp;nbsp;사용자만&amp;nbsp;접근하도록&amp;nbsp;처리 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;@login_required&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;change_password(request): &lt;br /&gt;new_pwd&amp;nbsp;=&amp;nbsp;request.POST.get('new_password','') &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;crnt_pwd&amp;nbsp;=&amp;nbsp;request.POST.get('current_password','')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;세션에서&amp;nbsp;로그인한&amp;nbsp;사용자정보를&amp;nbsp;가져온다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;user&amp;nbsp;=&amp;nbsp;'%s'&amp;nbsp;%&amp;nbsp;escape(request.session['userid'])&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;crnt_h&amp;nbsp;=&amp;nbsp;hashlib.sha256(crnt_pwd.encode()) &lt;br /&gt;h_pwd&amp;nbsp;=&amp;nbsp;crnt_h.hexdigest()&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;DB에서&amp;nbsp;기존&amp;nbsp;사용자의&amp;nbsp;Hash된&amp;nbsp;패스워드&amp;nbsp;가져오기 &lt;br /&gt;old_pwd&amp;nbsp;=&amp;nbsp;get_password_from_db(user)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;패스워드를&amp;nbsp;변경하기&amp;nbsp;전&amp;nbsp;사용자에&amp;nbsp;대해&amp;nbsp;재인증한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;old_pwd&amp;nbsp;==&amp;nbsp;h_pwd:&lt;/span&gt; &lt;br /&gt;new_h&amp;nbsp;=&amp;nbsp;hashlib.sha256(new_pwd.encode()) &lt;br /&gt;update_password_from_db(user,&amp;nbsp;new_h.hexdigest()) &lt;br /&gt;returnrender(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <category>데이터베이스</category>
      <category>시큐어코딩</category>
      <category>패스워드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/38</guid>
      <comments>https://fathersit.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 10 Aug 2022 22:15:34 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 서버 사이드 요청 위조</title>
      <link>https://fathersit.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wRFaV/btrJm7bK1YV/W1n3oAj7g2u7fkiuaRZ0Fk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wRFaV/btrJm7bK1YV/W1n3oAj7g2u7fkiuaRZ0Fk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wRFaV/btrJm7bK1YV/W1n3oAj7g2u7fkiuaRZ0Fk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwRFaV%2FbtrJm7bK1YV%2FW1n3oAj7g2u7fkiuaRZ0Fk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서버사이드 요청 위조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;적절한&amp;nbsp;검증절차를&amp;nbsp;거치지&amp;nbsp;않은&amp;nbsp;사용자&amp;nbsp;입력값을&amp;nbsp;서버간의&amp;nbsp;요청에&amp;nbsp;사용하여&amp;nbsp;악의적&amp;nbsp;인&amp;nbsp;행위가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;외부에 노출된 웹 서버에 취약한 애플리케이션이 존재하는 경우 공격자는 URL 또는 요청문을 위조하여 접근&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;통제를 우회하는&amp;nbsp;방식으로&amp;nbsp;비정상적인&amp;nbsp;동작을&amp;nbsp;유도하거나&amp;nbsp;신뢰된&amp;nbsp;네트워크에&amp;nbsp;있는&amp;nbsp;데이터를&amp;nbsp;획득할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;식별할 수 있는 범위 내에서 사용자의 입력 값을 다른 시스템의 서비스 호출에 사용하는 경우, 사용자의 입력 값을 화이트리스트&amp;nbsp;방식으로&amp;nbsp;필터링한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;사용자가 지정하는 무작위의 URL을 받아들여야 한다면 내부의 URL을 블랙리스트로 지정하여 필터링 한다. 또한 동일한 내부&amp;nbsp;네트워크에&amp;nbsp;있더라도&amp;nbsp;기기&amp;nbsp;인증,&amp;nbsp;접근권한을&amp;nbsp;확인하여&amp;nbsp;요청이&amp;nbsp;이루어질&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 삽입 코드의 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 192px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;삽입&amp;nbsp;코드의&amp;nbsp;예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 20px;&quot;&gt;내부망&amp;nbsp;중요&amp;nbsp;정보&amp;nbsp;획득&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 20px;&quot;&gt;http://sample_site.com/connect?url=http://192.168.0.45/member/list.json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 40px;&quot;&gt;외부 접근 차단된 admin&amp;nbsp;페이지&amp;nbsp;접근&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 40px;&quot;&gt;http://sample_site.com/connect?url=http://192.168.0.45/admin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 40px;&quot;&gt;도메인 체크를 우회하여 중요&amp;nbsp;정보&amp;nbsp;획득&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 40px;&quot;&gt;http://sample_site.com/connect?url=http://sample_site.com:x@192.168.0.45/member/list.json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 40px;&quot;&gt;단축 URL을 이용한 Filter&amp;nbsp;우회&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 40px;&quot;&gt;http://sample_site.com/connect?url=http://bit.ly/sdjk3kjhkl3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 16px;&quot;&gt;도메인을 사설IP로 설정 해 중요정보&amp;nbsp;획득&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 16px;&quot;&gt;http://sample_site.com/connect?url=http://192.168.0.45/member/list.json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 25.4651%; height: 16px;&quot;&gt;서버 내 파일 열람&lt;/td&gt;
&lt;td style=&quot;width: 74.5349%; height: 16px;&quot;&gt;http://sample_site.com/connect?url=file:///etc/passwd&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 안전하지 않은 코드 예제이다. 9라인의 사용자로부터 입력된 URL 주소를 검증 없이 사용하여 의도하지 않은 다른&amp;nbsp;서버의&amp;nbsp;자원에&amp;nbsp;접근&amp;nbsp;가능하게&amp;nbsp;된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;import&amp;nbsp;requests&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;call_third_party_api(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;addr&amp;nbsp;=&amp;nbsp;request.POST.get('address',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자가&amp;nbsp;입력한&amp;nbsp;주소를&amp;nbsp;검증하지&amp;nbsp;않고&amp;nbsp;HTTP&amp;nbsp;요청을&amp;nbsp;보내고&amp;nbsp;응답을 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자에게&amp;nbsp;반환&lt;/span&gt; &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;requests.get(addr).text&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/result.html',&amp;nbsp;{'result':result})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;안전한 코드는 다음과 같이 사전에 정의된 서버 목록을 정의하고 매칭되는 URL만 사용할 수 있으므로 URL 값을 임의로 조작할&amp;nbsp;수&amp;nbsp;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;import&amp;nbsp;requests&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;도메인을&amp;nbsp;화이트리스트에&amp;nbsp;정의&amp;nbsp;할&amp;nbsp;경우&amp;nbsp;DNS&amp;nbsp;rebinding&amp;nbsp;공격&amp;nbsp;등에 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;노출될&amp;nbsp;위험이&amp;nbsp;있어&amp;nbsp;신뢰&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;자원에&amp;nbsp;대한&amp;nbsp;IP를&amp;nbsp;사용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;검증하는&amp;nbsp;것이&amp;nbsp;좀더&amp;nbsp;안전하다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ALLOW_SERVER_LIST&amp;nbsp;=&amp;nbsp;[ &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'https://127.0.0.1/latest/', &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'https://192.168.0.1/user_data', &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'https://192.168.0.100/v1/public' &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;call_third_party_api(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;addr&amp;nbsp;=&amp;nbsp;request.POST.get('address',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자가&amp;nbsp;입력한&amp;nbsp;URL을&amp;nbsp;화이트리스트로&amp;nbsp;검증한&amp;nbsp;후&amp;nbsp;그&amp;nbsp;결과를&amp;nbsp;반환하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;검증되지&amp;nbsp;않은&amp;nbsp;주소로&amp;nbsp;요청을&amp;nbsp;보내지&amp;nbsp;않도록&amp;nbsp;제한한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;addr&amp;nbsp;not&amp;nbsp;in&amp;nbsp;ALLOW_SERVER_LIST:&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{error&amp;nbsp;=&amp;nbsp;'허용되지&amp;nbsp;않은&amp;nbsp;서버입니다.'})&lt;br /&gt;&lt;br /&gt;result&amp;nbsp;=&amp;nbsp;requests.get(addr).text &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/result.html',&amp;nbsp;{'result':result})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/37</guid>
      <comments>https://fathersit.tistory.com/37#entry37comment</comments>
      <pubDate>Wed, 10 Aug 2022 22:08:53 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 종료되지 않는 반복문 또는 재귀 함수</title>
      <link>https://fathersit.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Ze8L/btrJqmlbz9Z/hAPDIIFCOCyKSjlX3AhPIk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Ze8L/btrJqmlbz9Z/hAPDIIFCOCyKSjlX3AhPIk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Ze8L/btrJqmlbz9Z/hAPDIIFCOCyKSjlX3AhPIk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Ze8L%2FbtrJqmlbz9Z%2FhAPDIIFCOCyKSjlX3AhPIk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 시간 및 상태&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동시 또는 거의 동시 수행을 지원하는 병렬 시스템이나 하나 이상의 프로세스가 동작되는 환경에서 시간 및 상태를 부적절하게&amp;nbsp;관리하여&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;종료되지 않는 반복문 또는 재귀 함수(시큐어코딩)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;재귀의 순환 횟수를 제어하지 못하여 할당된 메모리나 프로그램 스택 등의 자원을 과다하게 사용하면 위험하다. 대부분의 경우, 귀납 조건(Base Case)이 없는 재귀 함수는 무한 루프에 빠져들게 되고 자원고갈을 유발함으로써 시스템의 정상적인 서비스를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;없게&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서는 최대 재귀 깊이가 적용되어 있어 무한루프가 발생하지 않으나, setrecursionlimit()를 사용하여 임의로 최대 재귀&amp;nbsp;깊이를&amp;nbsp;변경하여&amp;nbsp;사용하는&amp;nbsp;경우&amp;nbsp;과도하게&amp;nbsp;많이&amp;nbsp;재귀&amp;nbsp;함수가&amp;nbsp;수행되지&amp;nbsp;않도록&amp;nbsp;주의하여야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 재귀 호출 시, 재귀 호출 횟수를 제한하거나, 초기 값을 설정(상수)하여 재귀 호출을 제한해야 한다. Python의recursionlimit 제한은 stack overflow를 막기 위한 방법이다. recursionlimit 값을 과도하게 큰 값으로 설정하지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;factorial 함수는 함수 내부에서 자신을 호출하는 함수로, 재귀문을 빠져 나오는 조건을 정의하고 있지 않아 시스템 장애를 유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;def&amp;nbsp;factorial(num): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;재귀함수&amp;nbsp;탈출조건을&amp;nbsp;설정하지&amp;nbsp;않아&amp;nbsp;동작&amp;nbsp;중&amp;nbsp;에러&amp;nbsp;발생&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;num&amp;nbsp;*&amp;nbsp;factorial(num&amp;nbsp;&amp;ndash;&amp;nbsp;1)&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;'__main__': &lt;br /&gt;itr&amp;nbsp;=&amp;nbsp;5 &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;factorial(itr) &lt;br /&gt;print(str(itr)&amp;nbsp;+&amp;nbsp;'&amp;nbsp;팩토리얼&amp;nbsp;값은&amp;nbsp;:&amp;nbsp;'&amp;nbsp;+&amp;nbsp;str(result))&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;무한루프를&amp;nbsp;사용하지&amp;nbsp;않고&amp;nbsp;특정&amp;nbsp;조건&amp;nbsp;또는&amp;nbsp;횟수에&amp;nbsp;따라&amp;nbsp;동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;def&amp;nbsp;factorial(num): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;재귀함수&amp;nbsp;사용&amp;nbsp;시에는&amp;nbsp;탈출&amp;nbsp;조건을&amp;nbsp;명시해야&amp;nbsp;한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;(num&amp;nbsp;==&amp;nbsp;0): &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;return&amp;nbsp;1&lt;/span&gt; &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;num&amp;nbsp;*&amp;nbsp;factorial(num&amp;nbsp;-&amp;nbsp;1)&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;'__main__': &lt;br /&gt;itr&amp;nbsp;=&amp;nbsp;5 &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;factorial(itr) &lt;br /&gt;print(str(itr)&amp;nbsp;+&amp;nbsp;'&amp;nbsp;팩토리얼&amp;nbsp;값은&amp;nbsp;:&amp;nbsp;'&amp;nbsp;+&amp;nbsp;str(result))&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python의&amp;nbsp;재귀&amp;nbsp;반복&amp;nbsp;제한(Recursion&amp;nbsp;Depth&amp;nbsp;Limit)은&amp;nbsp;기본이&amp;nbsp;1000으로&amp;nbsp;설정되어&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Anaconda의&amp;nbsp;경우는&amp;nbsp;기본&amp;nbsp;값이&amp;nbsp;2000이다.&amp;nbsp;이&amp;nbsp;값을&amp;nbsp;과도하게&amp;nbsp;변경하지&amp;nbsp;않아야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;sys&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;sys.setrecursionlimit(1000)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/36</guid>
      <comments>https://fathersit.tistory.com/36#entry36comment</comments>
      <pubDate>Wed, 10 Aug 2022 22:00:36 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 크로스사이트 요청 위조(CSRF)</title>
      <link>https://fathersit.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dF0iKR/btrJpd3AZw9/hHJ1Z2KNK8W1BjziLq3qwK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dF0iKR/btrJpd3AZw9/hHJ1Z2KNK8W1BjziLq3qwK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dF0iKR/btrJpd3AZw9/hHJ1Z2KNK8W1BjziLq3qwK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdF0iKR%2FbtrJpd3AZw9%2FhHJ1Z2KNK8W1BjziLq3qwK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;크로스사이트 요청 위조(CSRF)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특정 웹사이트에 대해서 사용자가 인지하지 못한 상황에서 사용자의 의도와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 요청하게 하는 공격을 말한다. 웹 응용프로그램이 사용자로부터 받은 요청에 대해서 사용자가 의도한 대로 작성되고 전송된 것인지 확인하지 않는 경우 발생 가능하고 특히 해당 사용자가 관리자인 경우 사용자 권한관리, 게시물 삭제, 사용자 등록&amp;nbsp;등&amp;nbsp;관리자&amp;nbsp;권한으로만&amp;nbsp;수행&amp;nbsp;가능한&amp;nbsp;기능을&amp;nbsp;공격자의&amp;nbsp;의도대로&amp;nbsp;실행시킬&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;공격자는 사용자가 인증한 세션이 특정 동작을 수행하여도 계속 유지되어 정상적인 요청과 비정상적인 요청을 구분하지 못 하는 점을 악용한다. 파이썬에서 가장 많이 사용하고 있는 Django 프레임워크와 Flask 프레임워크에서는 각각 CSRF 토큰 기능을 지원하고 있으며, Django는 {% csrf token %} 태그를 이용하여 CSRF 토큰 기능 제공하고 Flask에서는 Flask-WTF 확장 라이브러리를 통해&amp;nbsp;{{form.csrf_token}}&amp;nbsp;태그를&amp;nbsp;이용하여&amp;nbsp;CSRF&amp;nbsp;토큰&amp;nbsp;기능을&amp;nbsp;제공하여&amp;nbsp;태그를&amp;nbsp;사용하는&amp;nbsp;경우&amp;nbsp;안전하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 요청이 정상적인 사용자의 정상적인 절차에 의한 요청인지를 구분하기 위해 세션별로 CSRF토큰을 생성하여 세션에 저장하고, 사용자가 작업페이지를 요청할 때마다 hidden값으로 클라이언트에게 토큰을 전달한 뒤, 해당 클라이언트의 데이터 처리&amp;nbsp;요청&amp;nbsp;시&amp;nbsp;전달되는&amp;nbsp;CSRF토큰값을&amp;nbsp;체크하여&amp;nbsp;요청의&amp;nbsp;유효성을&amp;nbsp;검사하도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Django 프레임워크와 Flask 프레임워크는 미들웨어와 프레임워크에서 기본적으로 CSRF Token을 사용해서 CSRF 공격으로부터&amp;nbsp;보호하는&amp;nbsp;기능을&amp;nbsp;가지고&amp;nbsp;있다.&amp;nbsp;해당&amp;nbsp;기능을&amp;nbsp;사용하기&amp;nbsp;위해&amp;nbsp;form태그&amp;nbsp;내부에&amp;nbsp;csrf_token을&amp;nbsp;사용해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Django&amp;nbsp;프레임워크&amp;nbsp;사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django프레임워크에서는 1.2 버전부터 CSRF 취약점을 방지기능을 기본으로 제공하고 있다. 미들웨어의 CSRF 옵션을 비활성하거나&amp;nbsp;템플릿에서&amp;nbsp;csrf_exempt&amp;nbsp;decorator를&amp;nbsp;사용하는&amp;nbsp;경우,&amp;nbsp;크로스사이트&amp;nbsp;요청&amp;nbsp;위조&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;⦁Django&amp;nbsp;미들웨어&amp;nbsp;설정(settings.py)&amp;nbsp;사례&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;MIDDLEWARE&amp;nbsp;=&amp;nbsp;[ &lt;br /&gt;'django.contrib.sessions.middleware.SessionMiddleware', &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;MIDDLEWARE&amp;nbsp;목록에서&amp;nbsp;csrf&amp;nbsp;항목을&amp;nbsp;삭제&amp;nbsp;또는&amp;nbsp;주석처리&amp;nbsp;하면 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;Django&amp;nbsp;앱에서&amp;nbsp;csrf&amp;nbsp;유효성&amp;nbsp;검사가&amp;nbsp;전역적으로&amp;nbsp;제거&amp;nbsp;됨 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;'django.middleware.csrf.CsrfViewMiddleware',&lt;/span&gt; &lt;br /&gt;'django.contrib.auth.middleware.AuthenticationMiddleware', &lt;br /&gt;'django.contrib.messages.middleware.MessageMiddleware', &lt;br /&gt;'django.middleware.locale.LocaleMiddleware', &lt;br /&gt;...... &lt;br /&gt;]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은&amp;nbsp;Django의&amp;nbsp;csrf&amp;nbsp;기능을&amp;nbsp;활성화하기&amp;nbsp;위한&amp;nbsp;안전한&amp;nbsp;미들웨어&amp;nbsp;설정&amp;nbsp;예제&amp;nbsp;이다. &lt;br /&gt;미들웨어의 csrf 기능을 주석, 또는 삭제 처리 하지 않아야 한다. 템플릿 페이지에는 csrf_token을 form 태그 안에 명시해야&amp;nbsp;미들웨어에서&amp;nbsp;정상적으로&amp;nbsp;csrf&amp;nbsp;기능을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;MIDDLEWARE&amp;nbsp;=&amp;nbsp;[ &lt;br /&gt;'django.contrib.sessions.middleware.SessionMiddleware', &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;MIDDLEWARE&amp;nbsp;목록에서&amp;nbsp;csrf&amp;nbsp;항목을&amp;nbsp;활성화&amp;nbsp;한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'django.middleware.csrf.CsrfViewMiddleware',&lt;/span&gt; &lt;br /&gt;'django.contrib.auth.middleware.AuthenticationMiddleware', &lt;br /&gt;'django.contrib.messages.middleware.MessageMiddleware', &lt;br /&gt;'django.middleware.locale.LocaleMiddleware', &lt;br /&gt;...... &lt;br /&gt;]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQLite DB-API 사용에서도 동일하게 정적인 쿼리문을 사전에 생성하고 사용자 입력을 바인딩 하여 안전하게 사용하여야 한다. SQLite에서 매개변수 화된 쿼리(Parameterized Query)를 만들기 위해 &amp;ldquo;?&amp;rdquo;를 Placeholder로 사용하거나 &amp;ldquo;:name&amp;rdquo; 처럼&amp;nbsp;Named&amp;nbsp;Placeholder를&amp;nbsp;사용하는&amp;nbsp;방법&amp;nbsp;2가지가&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;⦁Django&amp;nbsp;뷰&amp;nbsp;기능&amp;nbsp;설정(views.py)&amp;nbsp;사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;미들웨어에 csrf 검증 기능이 활성화 되어 있어도 View에서 csrf기능을 해제 하는 경우에는 해당 요청에 대해서 csrf 검증기능을&amp;nbsp;사용하지&amp;nbsp;않게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;다음은&amp;nbsp;Function-Based&amp;nbsp;View에서&amp;nbsp;csrf&amp;nbsp;검증&amp;nbsp;기능을&amp;nbsp;비활성화&amp;nbsp;하는&amp;nbsp;예제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;django.views.decorators.csrf&amp;nbsp;import&amp;nbsp;csrf_exempt&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;csrf.exempt&amp;nbsp;데코레이터로&amp;nbsp;미들웨어에서&amp;nbsp;보호되는&amp;nbsp;CSRF&amp;nbsp;기능을&amp;nbsp;해제한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;@csrf.exempt&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;pay_to_point(request): &lt;br /&gt;user_id&amp;nbsp;=&amp;nbsp;request.POST.get('user_id',&amp;nbsp;'') &lt;br /&gt;pay&amp;nbsp;=&amp;nbsp;request.POST.get('pay',&amp;nbsp;'') &lt;br /&gt;product_info&amp;nbsp;=&amp;nbsp;request.POST.get('product_info',&amp;nbsp;'') &lt;br /&gt;ret&amp;nbsp;=&amp;nbsp;pay(user_id,&amp;nbsp;pay,&amp;nbsp;product_info) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/view_wallet.html',&amp;nbsp;{'wallet':ret})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django는 기본적으로 CSRF 기능을 강제하고 있지만 몇몇 기능에 대해서 CSRF 기능을 해제 하여야 하는 경우는 미들웨어의 csrf 기능을 전역적으로 disable 하기 보다는 미들웨어의 csrf 기능은 활성화 하고 필요한 요청에 대해서만 csrf_exempt 데코레이터를&amp;nbsp;사용하여야&amp;nbsp;하고&amp;nbsp;이&amp;nbsp;경우에&amp;nbsp;크로스사이트&amp;nbsp;요청&amp;nbsp;위조의&amp;nbsp;위협에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;주의를&amp;nbsp;기울여야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;django.template&amp;nbsp;import&amp;nbsp;RequestContext&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;csrf_exempt&amp;nbsp;데코레이터를&amp;nbsp;삭제하거나&amp;nbsp;주석처리한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;@csrf_exempt &lt;/span&gt;&lt;br /&gt;def&amp;nbsp;pay_to_point(request): &lt;br /&gt;user_id&amp;nbsp;=&amp;nbsp;request.POST.get('user_id',&amp;nbsp;'') &lt;br /&gt;pay&amp;nbsp;=&amp;nbsp;request.POST.get('pay',&amp;nbsp;'') &lt;br /&gt;product_info&amp;nbsp;=&amp;nbsp;request.POST.get('product_info',&amp;nbsp;'')&lt;br /&gt;&lt;br /&gt;ret&amp;nbsp;=&amp;nbsp;pay(user_id,&amp;nbsp;pay,&amp;nbsp;product_info)&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/view_wallet.html',&amp;nbsp;{'wallet':ret})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;⦁Django&amp;nbsp;템플릿&amp;nbsp;설정&amp;nbsp;사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;미들웨어에서&amp;nbsp;csrf&amp;nbsp;기능을&amp;nbsp;활성화&amp;nbsp;하여도&amp;nbsp;템플릿&amp;nbsp;페이지에&amp;nbsp;csrf&amp;nbsp;토큰을&amp;nbsp;명시하지&amp;nbsp;않을&amp;nbsp;경우&amp;nbsp;csrf&amp;nbsp;검증&amp;nbsp;기능을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;&amp;lt;!--html&amp;nbsp;page--&amp;gt; &lt;br /&gt;&amp;lt;form&amp;nbsp;action=&quot;&quot;&amp;nbsp;method=&quot;POST&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;lt;!--&amp;nbsp;form&amp;nbsp;태그&amp;nbsp;내부에&amp;nbsp;csrf_token&amp;nbsp;미적용--&amp;gt;&lt;/span&gt; &lt;br /&gt;&amp;lt;table&amp;gt; &lt;br /&gt;{{form.as_table}} &lt;br /&gt;&amp;lt;/table&amp;gt; &lt;br /&gt;&amp;lt;input&amp;nbsp;type=&quot;submit&quot;/&amp;gt; &lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;미들웨어에서 csrf 기능을 활성화한 후에 템플릿 페이지에서는 csrf_token 값을 명시하여야만 정상적인 csrf 검증 기능을 사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;!--html&amp;nbsp;page--&amp;gt; &lt;br /&gt;&amp;lt;form&amp;nbsp;action=&quot;&quot;&amp;nbsp;method=&quot;POST&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;{%&amp;nbsp;csrf_token&amp;nbsp;%}&amp;nbsp;&amp;lt;!--csrf_token&amp;nbsp;사용-&amp;gt;&lt;/span&gt; &lt;br /&gt;&amp;lt;table&amp;gt; &lt;br /&gt;{{form.as_table}} &lt;br /&gt;&amp;lt;/table&amp;gt; &lt;br /&gt;&amp;lt;input&amp;nbsp;type=&quot;submit&quot;/&amp;gt; &lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Flask&amp;nbsp;프레임워크&amp;nbsp;사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;⦁Flask&amp;nbsp;app&amp;nbsp;설정&amp;nbsp;사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Flask의 WTF 패키지를 사용하면 CSRF 보호 기법을 사용 할 수 있다. 아래&amp;nbsp;예제&amp;nbsp;코드는&amp;nbsp;CSRF&amp;nbsp;설정이&amp;nbsp;되지&amp;nbsp;않은&amp;nbsp;상태이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask&lt;br /&gt;&lt;br /&gt;app&amp;nbsp;=&amp;nbsp;Flask(__name__)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Flask 프레임워크를 사용하여 웹 애플리케이션을 구축하는 경우, CSRF를 방지하려면 Flask-WTF extension의 CSRFProtect를&amp;nbsp;사용해야&amp;nbsp;한다.&amp;nbsp;app에&amp;nbsp;설정하고&amp;nbsp;HTML(템플릿)&amp;nbsp;페이지에는&amp;nbsp;CSRF토큰을&amp;nbsp;추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;from&amp;nbsp;flask_wtf.csrf&amp;nbsp;import&amp;nbsp;CSRFProtect&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;CSRF&amp;nbsp;설정&amp;nbsp;추가 &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;csrf&amp;nbsp;=&amp;nbsp;CSRFProtect(app)&lt;/span&gt; &lt;br /&gt;app&amp;nbsp;=&amp;nbsp;Flask(__name__) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;app.config[&amp;lsquo;SECRET_KEY&amp;rsquo;]&amp;nbsp;=&amp;nbsp;os.environ.get('SECRET_KEY') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;csrf.init_app(app)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;⦁Flask&amp;nbsp;템플릿&amp;nbsp;설정&amp;nbsp;사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 코드처럼 함수에 CSRF 기능을 활성화 하여도 Html 파일에 csrf_token을 명시 하지 않을 경우 CSRF 검증 기능을 사용할&amp;nbsp;수&amp;nbsp;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;&amp;lt;form&amp;nbsp;action=&quot;&quot;&amp;nbsp;method=&quot;POST&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;lt;!--&amp;nbsp;form&amp;nbsp;태그&amp;nbsp;내부에&amp;nbsp;csrf_token&amp;nbsp;미적용--&amp;gt;&lt;/span&gt; &lt;br /&gt;&amp;lt;table&amp;gt; &lt;br /&gt;{{as_table}} &lt;br /&gt;&amp;lt;/table&amp;gt; &lt;br /&gt;&amp;lt;input&amp;nbsp;type=&quot;submit&quot;/&amp;gt; &lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;템플릿&amp;nbsp;페이지에도&amp;nbsp;csrf_token&amp;nbsp;값을&amp;nbsp;명시해줘야&amp;nbsp;정상적인&amp;nbsp;csrf&amp;nbsp;검증이&amp;nbsp;수행된다. &lt;br /&gt;FlaskForm 사용 시에는 {{ form.csrf_token }}을 명시해야 하고 템플릿에 FlaskForm을 사용하지 않을 경우에는 form 태그&amp;nbsp;안에&amp;nbsp;hidden&amp;nbsp;input&amp;nbsp;값으로&amp;nbsp;{{&amp;nbsp;csrf_token&amp;nbsp;}}&amp;nbsp;값을&amp;nbsp;명시해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;form&amp;nbsp;action=&quot;&quot;&amp;nbsp;method=&quot;POST&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&amp;lt;!--&amp;nbsp;form&amp;nbsp;태그&amp;nbsp;내부에&amp;nbsp;csrf_token&amp;nbsp;적용--&amp;gt;&lt;/span&gt; &lt;br /&gt;&amp;lt;input&amp;nbsp;type=&quot;hidden&quot;&amp;nbsp;name=&quot;csrf_token&quot;&amp;nbsp;value=&quot;&lt;span style=&quot;color: #006dd7;&quot;&gt;{{&amp;nbsp;csrf_token&amp;nbsp;}}&lt;/span&gt;&quot;&amp;nbsp;/&amp;gt; &lt;br /&gt;&amp;lt;table&amp;gt; &lt;br /&gt;{{table}} &lt;br /&gt;&amp;lt;/table&amp;gt; &lt;br /&gt;&amp;lt;input&amp;nbsp;type=&quot;submit&quot;/&amp;gt; &lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/35</guid>
      <comments>https://fathersit.tistory.com/35#entry35comment</comments>
      <pubDate>Wed, 10 Aug 2022 21:56:06 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 제거되지 않고 남은 디버그 코드</title>
      <link>https://fathersit.tistory.com/34</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nksSj/btrJreAaGNV/pUaq78gJPegkzjsQPJUsa1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nksSj/btrJreAaGNV/pUaq78gJPegkzjsQPJUsa1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nksSj/btrJreAaGNV/pUaq78gJPegkzjsQPJUsa1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnksSj%2FbtrJreAaGNV%2FpUaq78gJPegkzjsQPJUsa1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 캡슐화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안약점으로 정보노출, 권한 문제 등이 발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제거되지 않고 남은 디버그 코드(시큐어코딩)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;디버깅 목적으로 삽입된 코드는 개발이 완료되면 제거해야 한다. 디버그 코드는 설정 등의 민감한 정보를 담거나 시스템을 제어하게&amp;nbsp;허용하는&amp;nbsp;부분을&amp;nbsp;담고&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;만일, 남겨진 채로 배포될 경우, 공격자가 식별 과정을 우회하거나 의도하지 않은&amp;nbsp;정보와&amp;nbsp;제어&amp;nbsp;정보가&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Django 프레임워크, Flask 프레임워크는 전역적으로 DEBUG 모드를 설정할 수 있다. DEBUG 모드를 사용하면 브라우저에서&amp;nbsp;임의의&amp;nbsp;Python&amp;nbsp;코드를&amp;nbsp;실행할&amp;nbsp;수도&amp;nbsp;있고&amp;nbsp;Python에서&amp;nbsp;발생한&amp;nbsp;모든&amp;nbsp;오류가&amp;nbsp;출력되어&amp;nbsp;정보노출의&amp;nbsp;위험이&amp;nbsp;있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어플리케이션을&amp;nbsp;배포&amp;nbsp;전에&amp;nbsp;반드시&amp;nbsp;DEBUG&amp;nbsp;모드를&amp;nbsp;비활성화&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;소프트웨어 배포 전, 반드시 디버그 코드를 확인 및 삭제한다. Django 프레임워크의 경우 전역적으로 DEBUG 모드를 비&amp;nbsp;활성화&amp;nbsp;하려면&amp;nbsp;settings.py&amp;nbsp;파일에&amp;nbsp;설정을&amp;nbsp;하고&amp;nbsp;Flask&amp;nbsp;프레임워크는&amp;nbsp;app_run()&amp;nbsp;전에&amp;nbsp;debug&amp;nbsp;=&amp;nbsp;False로&amp;nbsp;설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은&amp;nbsp;Django의&amp;nbsp;미들웨어&amp;nbsp;세팅&amp;nbsp;파일인&amp;nbsp;settings.py&amp;nbsp;파일이다.&amp;nbsp;개발&amp;nbsp;시&amp;nbsp;사용된&amp;nbsp;DEBUG&amp;nbsp;옵션이&amp;nbsp;True로&amp;nbsp;설정되어&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Django 예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.urls&amp;nbsp;import&amp;nbsp;reverse_lazy &lt;br /&gt;from&amp;nbsp;django.utils.text&amp;nbsp;import&amp;nbsp;format_lazy&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;DEBUG&amp;nbsp;=&amp;nbsp;True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ROOT_URLCONF&amp;nbsp;=&amp;nbsp;'test.urls' &lt;br /&gt;SITE_ID&amp;nbsp;=&amp;nbsp;1&lt;br /&gt;&lt;br /&gt;DATABASES&amp;nbsp;=&amp;nbsp;{ &lt;br /&gt;'default':&amp;nbsp;{ &lt;br /&gt;'ENGINE':&amp;nbsp;'django.db.backends.sqlite3', &lt;br /&gt;'NAME':&amp;nbsp;':memory:', &lt;br /&gt;} &lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발이&amp;nbsp;끝난&amp;nbsp;소스코드를&amp;nbsp;운영,&amp;nbsp;배포&amp;nbsp;할&amp;nbsp;경우에는&amp;nbsp;DEBUG&amp;nbsp;옵션을&amp;nbsp;False로&amp;nbsp;변경해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.urls&amp;nbsp;import&amp;nbsp;reverse_lazy &lt;br /&gt;from&amp;nbsp;django.utils.text&amp;nbsp;import&amp;nbsp;format_lazy&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;DEBUG&amp;nbsp;=&amp;nbsp;False&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ROOT_URLCONF&amp;nbsp;=&amp;nbsp;'test.urls' &lt;br /&gt;SITE_ID&amp;nbsp;=&amp;nbsp;1&lt;br /&gt;&lt;br /&gt;DATABASES&amp;nbsp;=&amp;nbsp;{ &lt;br /&gt;'default':&amp;nbsp;{ &lt;br /&gt;'ENGINE':&amp;nbsp;'django.db.backends.sqlite3', &lt;br /&gt;'NAME':&amp;nbsp;':memory:', &lt;br /&gt;} &lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Flask 예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은&amp;nbsp;Flask의&amp;nbsp;예제로&amp;nbsp;debug&amp;nbsp;모드가&amp;nbsp;True로&amp;nbsp;설정되어&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask&lt;br /&gt;&lt;br /&gt;app&amp;nbsp;=&amp;nbsp;Flask(__name__) &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;app.debug&amp;nbsp;=&amp;nbsp;True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@app.route('/') &lt;br /&gt;def&amp;nbsp;hello_world(): &lt;br /&gt;return&amp;nbsp;'Hello&amp;nbsp;World!'&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;'__main__': &lt;br /&gt;app.run()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발이&amp;nbsp;끝난&amp;nbsp;소스코드를&amp;nbsp;운영,&amp;nbsp;배포&amp;nbsp;할&amp;nbsp;경우에는&amp;nbsp;debug&amp;nbsp;옵션을&amp;nbsp;False로&amp;nbsp;변경해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask&lt;br /&gt;&lt;br /&gt;app&amp;nbsp;=&amp;nbsp;Flask(__name__) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;app.debug&amp;nbsp;=&amp;nbsp;False&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@app.route('/') &lt;br /&gt;def&amp;nbsp;hello_world(): &lt;br /&gt;return&amp;nbsp;'Hello&amp;nbsp;World!'&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;'__main__': &lt;br /&gt;app.run()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/34</guid>
      <comments>https://fathersit.tistory.com/34#entry34comment</comments>
      <pubDate>Wed, 10 Aug 2022 21:41:04 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 보안기능 결정에 사용되는 부적절한 입력값</title>
      <link>https://fathersit.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5VIJc/btrJlVA0i0S/8urGVVdqdx29gwGlHm0hEK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5VIJc/btrJlVA0i0S/8urGVVdqdx29gwGlHm0hEK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5VIJc/btrJlVA0i0S/8urGVVdqdx29gwGlHm0hEK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5VIJc%2FbtrJlVA0i0S%2F8urGVVdqdx29gwGlHm0hEK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;보안기능 결정에 사용되는 부적절한 입력값&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응용프로그램이 외부 입력값에 대한 신뢰를 전제로 보호메커니즘을 사용하는 경우 공격자가 입력값을 조작할 수 있다면 보호메커니즘을&amp;nbsp;우회할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;개발자들이 흔히 쿠키, 환경변수 또는 히든필드와 같은 입력값이 조작될 수 없다고 가정하지만 공격자는 다양한 방법을 통해 이러한 입력값들을 변경할 수 있고 조작된 내용은 탐지되지 않을 수 있다. 인증이나 인가와 같은 보안결정이 이런 입력값(쿠키, 환경변수, 히든필드 등)에 기반을 두어 수행되는 경우 공격자는 이런 입력값을 조작하여 응용프로그램의 보안을 우회할 수 있으므로&amp;nbsp;충분한&amp;nbsp;암호화,&amp;nbsp;무결성&amp;nbsp;체크를&amp;nbsp;수행하고&amp;nbsp;이와&amp;nbsp;같은&amp;nbsp;메커니즘이&amp;nbsp;없는&amp;nbsp;경우엔&amp;nbsp;외부사용자에&amp;nbsp;의한&amp;nbsp;입력값을&amp;nbsp;신뢰해서는&amp;nbsp;안&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;파이썬의 Djagno 프레임워크에서 세션을 관리하는 기능을 제공하고 있어 이 기능사용 시에는 세션쿠키의 만료 시점을 설정하여 사용할 수 있으며 DRF(Django Rest Framework)에서 제공하는 토큰 및 세션 기능을 사용하여 안전하게 구성할 수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;상태정보나&amp;nbsp;민감한&amp;nbsp;데이터&amp;nbsp;특히&amp;nbsp;사용자&amp;nbsp;세션정보와&amp;nbsp;같은&amp;nbsp;중요한&amp;nbsp;정보는&amp;nbsp;서버에&amp;nbsp;저장하고&amp;nbsp;보안확인&amp;nbsp;절차도&amp;nbsp;서버에서&amp;nbsp;실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;보안설계관점에서 신뢰할 수 없는 입력 값이 응용프로그램 내부로 들어올 수 있는 지점과 보안결정에 사용되는 입력 값을 식별하고&amp;nbsp;제공되는&amp;nbsp;입력&amp;nbsp;값에&amp;nbsp;의존할&amp;nbsp;필요가&amp;nbsp;없는&amp;nbsp;구조로&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있는지&amp;nbsp;검토한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전하지 않은 코드로 쿠키에 저장된 권한 등급을 가져와 관리자인지 확인 후에 사용자의 패스워드를 초기화 하고 메일을&amp;nbsp;보내는&amp;nbsp;예제이다.&amp;nbsp;5라인에서&amp;nbsp;쿠키에서&amp;nbsp;등급을&amp;nbsp;가져와&amp;nbsp;9라인에서&amp;nbsp;관리자인지&amp;nbsp;확인하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;init_password(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;쿠키에서&amp;nbsp;권한&amp;nbsp;정보를&amp;nbsp;가져옴 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;roll&amp;nbsp;=&amp;nbsp;request.COOKIE['roll'] &lt;/span&gt;&lt;br /&gt;request_id&amp;nbsp;=&amp;nbsp;request.POST.get('user_id',&amp;nbsp;'') &lt;br /&gt;request_mail&amp;nbsp;=&amp;nbsp;request.POST.get('user_email','') &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;쿠키에서&amp;nbsp;가져온&amp;nbsp;권한이&amp;nbsp;관리자인지&amp;nbsp;비교 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;if&amp;nbsp;roll&amp;nbsp;==&amp;nbsp;'admin' &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;패스워드&amp;nbsp;초기화&amp;nbsp;및&amp;nbsp;메일&amp;nbsp;발송&amp;nbsp;처리&lt;/span&gt; &lt;br /&gt;password_init_and_sendmail(request_id,&amp;nbsp;request_mail) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/sucess.html') &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/failed.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중요기능을&amp;nbsp;수행하는&amp;nbsp;결정을&amp;nbsp;위한&amp;nbsp;데이터는&amp;nbsp;위변조&amp;nbsp;가능성이&amp;nbsp;높은&amp;nbsp;쿠키보다&amp;nbsp;세션에&amp;nbsp;저장하도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;def&amp;nbsp;init_password(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;세션에서&amp;nbsp;권한&amp;nbsp;정보를&amp;nbsp;가져옴 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;roll&amp;nbsp;=&amp;nbsp;request.session['roll']&lt;/span&gt; &lt;br /&gt;request_id&amp;nbsp;=&amp;nbsp;request.POST.get('user_id',&amp;nbsp;'') &lt;br /&gt;request_mail&amp;nbsp;=&amp;nbsp;request.POST.get('user_email','') &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;세션에서&amp;nbsp;가져온&amp;nbsp;권한이&amp;nbsp;관리자인지&amp;nbsp;비교 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;roll&amp;nbsp;==&amp;nbsp;&amp;lsquo;admin&amp;rsquo; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;패스워드&amp;nbsp;초기화&amp;nbsp;및&amp;nbsp;메일&amp;nbsp;발송&amp;nbsp;처리&lt;/span&gt; &lt;br /&gt;password_init_and_sendmail(request_id,&amp;nbsp;request_mail) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/sucess.html') &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/failed.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/33</guid>
      <comments>https://fathersit.tistory.com/33#entry33comment</comments>
      <pubDate>Wed, 10 Aug 2022 02:13:49 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] LDAP 삽입</title>
      <link>https://fathersit.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZUWt9/btrJljbc21H/jlXIExQnqHg1xcqVRzX1h0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZUWt9/btrJljbc21H/jlXIExQnqHg1xcqVRzX1h0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZUWt9/btrJljbc21H/jlXIExQnqHg1xcqVRzX1h0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZUWt9%2FbtrJljbc21H%2FjlXIExQnqHg1xcqVRzX1h0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LDAP 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공격자가&amp;nbsp;외부&amp;nbsp;입력을&amp;nbsp;통해서&amp;nbsp;의도하지&amp;nbsp;않은&amp;nbsp;LDAP(LightweightDirectoryAccessProtocol)&amp;nbsp;명령어를&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;즉, 웹 응용프로그램이 사용자가 제공한 입력을 올바르게 처리하지 못하면, 공격자가 LDAP 명령문의 구성을 바꿀 수 있다. 이로&amp;nbsp;인해&amp;nbsp;프로세스가&amp;nbsp;명령을&amp;nbsp;실행한&amp;nbsp;컴포넌트와&amp;nbsp;동일한&amp;nbsp;권한(Permission)을&amp;nbsp;가지고&amp;nbsp;동작하게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;외부 입력값을 적절한 처리 없이 LDAP 쿼리문이나 결과의 일부로 사용하는 경우, LDAP 쿼리문이 실행될 때 공격자는 LDAP 쿼리문의 내용을 마음대로 변경할 수 있다. Python에는 Python-ldap 및 ldap3라는 두 개의 라이브러리가 있다. ldap3가 python-ldap 보다 더 현대적인 라이브러리 이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ldap3 모듈은 Python 2.6부터 모든 Python 3 버전에 호환된다. ldap3에서는 좀 더 Python적인 방식으로 LDAP서버와 상호 작용할 수 있는 완전한 기능의 추상화 계층이 포함되어 있다. python-ldap은 OpenLDAP에서 만든 Python2의 패키지로 Python3에서는 ldap3 라이브러리를 사용하는 것이 권장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른&amp;nbsp;삽입&amp;nbsp;공격과&amp;nbsp;마찬가지로&amp;nbsp;LDAP&amp;nbsp;삽입에&amp;nbsp;대한&amp;nbsp;기본적인&amp;nbsp;방어&amp;nbsp;방법은&amp;nbsp;적절한&amp;nbsp;유효성&amp;nbsp;검사이다. &lt;br /&gt;⦁올바른&amp;nbsp;인코딩(Encoding)&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;모든&amp;nbsp;변수&amp;nbsp;이스케이프(Escape) &lt;br /&gt;⦁화이트리스트&amp;nbsp;방식의&amp;nbsp;입력&amp;nbsp;값&amp;nbsp;유효성&amp;nbsp;검사 &lt;br /&gt;⦁사용자&amp;nbsp;비밀번호와&amp;nbsp;같은&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;포함된&amp;nbsp;필드&amp;nbsp;인덱싱 &lt;br /&gt;⦁LDAP&amp;nbsp;바인딩&amp;nbsp;계정에&amp;nbsp;할당된&amp;nbsp;권한&amp;nbsp;최소화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자의&amp;nbsp;입력을&amp;nbsp;바로&amp;nbsp;LDAP&amp;nbsp;질의문에&amp;nbsp;사용하고&amp;nbsp;있으며&amp;nbsp;이&amp;nbsp;경우&amp;nbsp;권한&amp;nbsp;상승&amp;nbsp;등의&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;ldap3&amp;nbsp;import&amp;nbsp;Connection,&amp;nbsp;Server,&amp;nbsp;ALL &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;ldap_query(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값으로&amp;nbsp;LDAP&amp;nbsp;쿼리문의&amp;nbsp;인자에&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용하면 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;search_keyword&amp;nbsp;=&amp;nbsp;request.POST.get('search_keyword','')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;dn&amp;nbsp;=&amp;nbsp;server.config['bind_dn'] &lt;br /&gt;password&amp;nbsp;=&amp;nbsp;server.config['password']&lt;br /&gt;&lt;br /&gt;address&amp;nbsp;=&amp;nbsp;'ldap.badSoruce.com' &lt;br /&gt;server&amp;nbsp;=&amp;nbsp;Server(address,&amp;nbsp;get_info=ALL) &lt;br /&gt;conn&amp;nbsp;=&amp;nbsp;Connection(server,&amp;nbsp;user=dn,&amp;nbsp;password,&amp;nbsp;auto_bind=True&amp;nbsp;)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자&amp;nbsp;입력을&amp;nbsp;필터링&amp;nbsp;하지&amp;nbsp;않는&amp;nbsp;경우&amp;nbsp;공격자의&amp;nbsp;권한&amp;nbsp;상승으로 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;이어질&amp;nbsp;수&amp;nbsp;있다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;search_str&amp;nbsp;=&amp;nbsp;'(&amp;amp;(objectclass=%s))'&amp;nbsp;%&amp;nbsp;search_keyword&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;conn.search('dc=company,dc=com',&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;search_str&lt;/span&gt;,&amp;nbsp;attributes=['sn',&amp;nbsp;'cn',&amp;nbsp;'address',&amp;nbsp;'mail',&amp;nbsp;'mobile',&amp;nbsp;'uid']) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/ldap_query_response.html',&amp;nbsp;{'ldap':conn.entries})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자의&amp;nbsp;입력&amp;nbsp;중&amp;nbsp;LDAP&amp;nbsp;질의문에&amp;nbsp;사용될&amp;nbsp;변수를&amp;nbsp;이스케이프&amp;nbsp;하여&amp;nbsp;질의문을&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;공격에&amp;nbsp;노출되는&amp;nbsp;것을&amp;nbsp;예방할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;ldap3&amp;nbsp;import&amp;nbsp;Connection,&amp;nbsp;Server,&amp;nbsp;ALL &lt;br /&gt;from&amp;nbsp;ldap3.utils.conv&amp;nbsp;import&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;escape_filter_chars&lt;/span&gt; &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;ldap_query(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;search_keyword&amp;nbsp;=&amp;nbsp;request.POST.get('search_keyword','')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;dn&amp;nbsp;=&amp;nbsp;server.config['bind_dn'] &lt;br /&gt;password&amp;nbsp;=&amp;nbsp;server.config['password']&lt;br /&gt;&lt;br /&gt;address&amp;nbsp;=&amp;nbsp;'ldap.goodsource.com' &lt;br /&gt;server&amp;nbsp;=&amp;nbsp;Server(address,&amp;nbsp;get_info=ALL) &lt;br /&gt;conn&amp;nbsp;=&amp;nbsp;Connection(server,&amp;nbsp;dn,&amp;nbsp;password,&amp;nbsp;auto_bind=True&amp;nbsp;)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;입력에&amp;nbsp;필터링을&amp;nbsp;적용하여&amp;nbsp;공격에&amp;nbsp;사용될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문자를 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;이스케이프하고&amp;nbsp;있다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;escpae_keyword&amp;nbsp;=&amp;nbsp;escape_filter_chars(search_keyword)&lt;/span&gt; &lt;br /&gt;search_str&amp;nbsp;=&amp;nbsp;'(&amp;amp;(objectclass=%s))'&amp;nbsp;%&amp;nbsp;escpae_keyword&lt;br /&gt;&lt;br /&gt;conn.search('dc=company,dc=com',&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;search_str&lt;/span&gt;,&amp;nbsp;attributes=['sn',&amp;nbsp;'cn',&amp;nbsp;'address',&amp;nbsp;'mail',&amp;nbsp;'mobile',&amp;nbsp;'uid']) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/ldap_query_response.html',&amp;nbsp;{'ldap':conn.entries})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/32</guid>
      <comments>https://fathersit.tistory.com/32#entry32comment</comments>
      <pubDate>Wed, 10 Aug 2022 02:10:00 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] XML 삽입</title>
      <link>https://fathersit.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6iPmr/btrJj5dA4A9/KW4QKuqLw7XiSZLxV1iFL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6iPmr/btrJj5dA4A9/KW4QKuqLw7XiSZLxV1iFL0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6iPmr/btrJj5dA4A9/KW4QKuqLw7XiSZLxV1iFL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6iPmr%2FbtrJj5dA4A9%2FKW4QKuqLw7XiSZLxV1iFL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;XML 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;검증되지 않은 외부 입력값이 XQuery 또는 XPath 쿼리문을 생성하는 문자열로 사용되어 공격자가 쿼리문의 구조로 임의로 변경하고&amp;nbsp;임의의&amp;nbsp;쿼리를&amp;nbsp;실행하여&amp;nbsp;허가되지&amp;nbsp;않은&amp;nbsp;데이터를&amp;nbsp;열람하거나&amp;nbsp;인증절차를&amp;nbsp;우회할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XQuery 또는 XPath 쿼리에 사용되는 외부 입력데이터에 대하여 특수문자 및 쿼리 예약어를 필터링 하고 파라미터화 (Parameterized)된&amp;nbsp;쿼리문을&amp;nbsp;지원하는&amp;nbsp;XQuery를&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 Python에서 XML 데이터를 처리하기 위한 기본 모듈인 xml.etree.ElementTree를 이용하여 사용자 정보를 가져오는 예제이다. xml.etree.ElementTree 모듈은 제한적인 Xpath 기능을 제공하고 Xpath표현식을 매개변수화 해서 사용하는&amp;nbsp;방법을&amp;nbsp;제공하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;lxml&amp;nbsp;import&amp;nbsp;etree&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;parse_xml(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;user_name&amp;nbsp;=&amp;nbsp;request.POST.get('user_name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;parser&amp;nbsp;=&amp;nbsp;etree.XMLParser(resolve_entities=False) &lt;br /&gt;tree&amp;nbsp;=&amp;nbsp;etree.parse('user.xml',&amp;nbsp;parser) &lt;br /&gt;root&amp;nbsp;=&amp;nbsp;tree.getroot()&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;검증되지&amp;nbsp;않은&amp;nbsp;외부&amp;nbsp;입력값&amp;nbsp;user_name를&amp;nbsp;사용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않은&amp;nbsp;질의문이&amp;nbsp;작성되에&amp;nbsp;query변수에&amp;nbsp;저장 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;path&amp;nbsp;=&amp;nbsp;&quot;/collection/users/user[@name='&quot;&amp;nbsp;+&amp;nbsp;user_name&amp;nbsp;+&amp;nbsp;&quot;']/home/text()&quot;&lt;/span&gt; &lt;br /&gt;elmts&amp;nbsp;=&amp;nbsp;root.xpath(query) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'parse_xml.html',&amp;nbsp;{'xml_element':elmts})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python 3.3 이후 보안상의 이유로 금지된 xml.etree.ElementTree 모듈 대신 lxml 라이브러리를 사용하고, 외부 입력값은&amp;nbsp;매개변수화&amp;nbsp;해서&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;lxml&amp;nbsp;import&amp;nbsp;etree&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;parse_xml(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;user_name&amp;nbsp;=&amp;nbsp;request.POST.get('user_name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;parser&amp;nbsp;=&amp;nbsp;etree.XMLParser(resolve_entities=False) &lt;br /&gt;tree&amp;nbsp;=&amp;nbsp;etree.parse('user.xml',&amp;nbsp;parser) &lt;br /&gt;oot = tree.getroot()&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;query&amp;nbsp;=&amp;nbsp;'/collection/users/user[@name&amp;nbsp;=&amp;nbsp;$paramname]/home/text()' &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#외부&amp;nbsp;입력값을&amp;nbsp;paramname으로&amp;nbsp;매개변수화&amp;nbsp;해서&amp;nbsp;사용&lt;/span&gt; &lt;br /&gt;elmts&amp;nbsp;=&amp;nbsp;root.xpath(query,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;paramname=user_name)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'parse_xml.html',&amp;nbsp;{'xml_element':elmts})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/31</guid>
      <comments>https://fathersit.tistory.com/31#entry31comment</comments>
      <pubDate>Wed, 10 Aug 2022 02:04:14 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 신뢰되지 않은 URL주소로 자동접속 연결</title>
      <link>https://fathersit.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LwhEj/btrJilgGIJm/1FScxTAeoMivFHFLD7zXQk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LwhEj/btrJilgGIJm/1FScxTAeoMivFHFLD7zXQk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LwhEj/btrJilgGIJm/1FScxTAeoMivFHFLD7zXQk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLwhEj%2FbtrJilgGIJm%2F1FScxTAeoMivFHFLD7zXQk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;신뢰되지 않은 URL주소로 자동접속 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자로부터 입력되는 값을 외부사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램은 피싱(Phishing) 공격에 노출되는 취약점을 가질 수 있다. 일반적으로 클라이언트에서 전송된 URL 주소로 연결하기 때문에 안전하다고 생각할 수 있으나, 공격자는 해당 폼의 요청을 변조함으로써 사용자가 위험한 URL로 접속할 수 있도록 공격할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python 프레임워크의 redirect 함수를 사용 할 때에도 해당 프레임워크 버전에서 알려진 취약점이 있는지 확인해야 한다. Flask 프레임워크의 Flask-Security-Too 라이브러리의 경우 get_post_logout_redirect 함수와 get_post_login_redirect 함수가 4.1.0 이전 버전에서 URL 유효성 검사를 우회하고 사용자를 임의의 URL로 리디렉션 할 수 있는 취약점이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;리디렉션을 허용하는 모든 URL을 서버 측 화이트리스트로 관리하고 사용자 입력 값을 리디렉션 할 URL이 존재하는지 검증해야 한다. 만약 사용자 입력 값이 화이트 리스트로 관리가 불가능하고 리디렉션 URL의 인자 값으로 사용되어야만 하는 경우는 모든 리디렉션에서 프로토콜과 host정보가 들어가지 않는 상대 URL(relative)을 사용해야 하고, 검증해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또는 절대 URL(absoute URL)을 사용할 경우 리디렉션을 실행하기 전에 사용자 입력 URL&amp;nbsp;&lt;a href=&quot;https://myhompage.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://myhompage.com/&lt;/a&gt; 처럼 서비스하고&amp;nbsp;있는&amp;nbsp;URL로&amp;nbsp;시작하는지를&amp;nbsp;확인해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전하지 않은 예제로 사용자로부터 입력 받은 url 주소를 검증 없이 reirect함수의 인자로 사용하고 있다. 이 경우 사용자가&amp;nbsp;의도하지&amp;nbsp;않은&amp;nbsp;사이트로&amp;nbsp;접근하도록&amp;nbsp;하거나&amp;nbsp;피싱(Phishing)공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;redirect&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;redirect_url(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;url_string&amp;nbsp;=&amp;nbsp;request.POST.get('url',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자&amp;nbsp;입력에&amp;nbsp;포함된&amp;nbsp;URL&amp;nbsp;주소로&amp;nbsp;리다이렉트&amp;nbsp;하는&amp;nbsp;경우 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;피싱&amp;nbsp;사이트로&amp;nbsp;접속되는&amp;nbsp;등&amp;nbsp;사용자가&amp;nbsp;피싱&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;return&amp;nbsp;redirect(url_string)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 코드 예제로 사용자로부터 주소를 입력받아 redirect하고 있는 코드로 위험한 도메인이 포함되어 있을 수 있기&amp;nbsp;때문에&amp;nbsp;화이트&amp;nbsp;리스트로&amp;nbsp;사전에&amp;nbsp;정의된&amp;nbsp;안전한&amp;nbsp;웹사이트에&amp;nbsp;한하여&amp;nbsp;redirect&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render,&amp;nbsp;redirect&lt;br /&gt;&lt;br /&gt;ALLOW_URL_LIST&amp;nbsp;=&amp;nbsp;[ &lt;br /&gt;'127.0.0.1', &lt;br /&gt;'192.168.0.1', &lt;br /&gt;'192.168.0.100', &lt;br /&gt;'&lt;a href=&quot;https://login.myservice.com',&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://login.myservice.com',&lt;/a&gt; &lt;br /&gt;'/notice' &lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;redirect_url(request): &lt;br /&gt;url_string&amp;nbsp;=&amp;nbsp;request.POST.get('url',&amp;nbsp;'')&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;이동할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;URL&amp;nbsp;범위를&amp;nbsp;제한하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;위험한&amp;nbsp;사이트의&amp;nbsp;접근을&amp;nbsp;차단하고&amp;nbsp;있다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;url_string&amp;nbsp;not&amp;nbsp;in&amp;nbsp;ALLOW_URL_LIST:&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'ERROR':'허용되지&amp;nbsp;않는&amp;nbsp;주소입니다.})&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;redirect(url_string)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/30</guid>
      <comments>https://fathersit.tistory.com/30#entry30comment</comments>
      <pubDate>Wed, 10 Aug 2022 01:23:33 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 위험한 형식 파일 업로드</title>
      <link>https://fathersit.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQQ6oM/btrJikhIbfP/QJU6k3q3CXmk14N74TmRP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQQ6oM/btrJikhIbfP/QJU6k3q3CXmk14N74TmRP1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQQ6oM/btrJikhIbfP/QJU6k3q3CXmk14N74TmRP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQQ6oM%2FbtrJikhIbfP%2FQJU6k3q3CXmk14N74TmRP1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;위험한 형식 파일 업로드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서버 측에서 실행될 수 있는 스크립트 파일(asp, jsp, php, sh 파일 등)이 업로드 가능하고, 이 파일을 공격자가 웹을 통해 직접&amp;nbsp;실행시킬&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;경우,&amp;nbsp;시스템&amp;nbsp;내부명령어를&amp;nbsp;실행하거나&amp;nbsp;외부와&amp;nbsp;연결하여&amp;nbsp;시스템을&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;공격자가 실행 가능한 파일을 서버에 업로드 하면 파이썬에서 String 형식으로 표현된 표현식을 인수로 받아 반환하는 eval() 함수와 인수로 받은 문자열을 실행하는 exec()를 같이 사용하여 여러 변수들을 동적으로 값을 할당받아 실행될 수 있어 웹쉘(Web&amp;nbsp;Shell)&amp;nbsp;공격에&amp;nbsp;취약하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파일 업로드 공격을 방지하기 위해서 특정 파일 유형만 허용하도록 화이트리스트 방식으로 파일 유형을 제한하여야 한다. 이때 파일의 확장자 및 업로드 된 파일의 Content-Type도 같이 확인한다. 파일 크기 및 파일 개수를 제한하여 시스템 자원 고갈&amp;nbsp;등으로&amp;nbsp;서비스&amp;nbsp;거부&amp;nbsp;공격이&amp;nbsp;발생하지&amp;nbsp;않도록&amp;nbsp;제한하여야&amp;nbsp;한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;업로드 된 파일을 웹 루트 폴더 외부에 저장하여 공격자가 URL을 통해 파일을 실행할 수 없도록 해야 하고 가능하면 업로드 되는 파일의 이름은 공격자가 추측할 수 없는 무작위한 이름으로 변경하여 저장하는 것이 안전하다. 또한 업로드 된 파일을 저장할 경우에는 최소 권한만 부여하는 것이 안전하고 실행&amp;nbsp;여부를&amp;nbsp;확인하여&amp;nbsp;실행권한을&amp;nbsp;삭제&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;업로드 할 파일에 대한 개수, 크기, 확장자 등의 유효성 검사를 하지 않고 파일시스템에 저장 할 경우 공격자에 의해 악성코드,&amp;nbsp;쉘&amp;nbsp;코드&amp;nbsp;등&amp;nbsp;위험한&amp;nbsp;형식의&amp;nbsp;파일을&amp;nbsp;시스템에&amp;nbsp;업로드&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;django.core.files.storage&amp;nbsp;import&amp;nbsp;FileSystemStorage&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;file_upload(request): &lt;br /&gt;if&amp;nbsp;request.FILES['upload_file']: &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자로부터&amp;nbsp;업로드&amp;nbsp;되는&amp;nbsp;파일에&amp;nbsp;대해&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;저장하고&amp;nbsp;있어 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;upload_file&amp;nbsp;=&amp;nbsp;request.FILES['upload_file']&lt;/span&gt; &lt;br /&gt;fs&amp;nbsp;=&amp;nbsp;FileSystemStorage(location='media/screenshot',&amp;nbsp;base_url='media/screenshot') &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;업로드&amp;nbsp;하는&amp;nbsp;파일에&amp;nbsp;대한&amp;nbsp;크기,&amp;nbsp;개수,&amp;nbsp;확장자&amp;nbsp;등을&amp;nbsp;검증&amp;nbsp;하지&amp;nbsp;않음.&lt;/span&gt; &lt;br /&gt;filename&amp;nbsp;=&amp;nbsp;fs.save(upload_file.name,&amp;nbsp;upload_file) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'filename':filename}) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'파일&amp;nbsp;업로드&amp;nbsp;실패'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 코드는 업로드 하는 파일의 파일 개수, 파일 크기, 파일 확장자 등을 검사하여 업로드를 제한하고 있다. 21라인의 파일 타입 확인은 MIME 타입을 확인하는 과정으로 파일이름에서 확장자만 검사할 경우 변조된 확장자를 통해 업로드 제한을 회피할&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;파일자체의&amp;nbsp;시그니처를&amp;nbsp;확인하는&amp;nbsp;과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;os &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;django.core.files.storage&amp;nbsp;import&amp;nbsp;FileSystemStorage&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;업로드&amp;nbsp;하는&amp;nbsp;파일에&amp;nbsp;대한&amp;nbsp;개수,&amp;nbsp;크기,&amp;nbsp;확장자&amp;nbsp;제한 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;FILE_COUNT_LIMIT&amp;nbsp;=&amp;nbsp;5 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;업로드&amp;nbsp;하는&amp;nbsp;파일의&amp;nbsp;최대&amp;nbsp;사이즈&amp;nbsp;제한&amp;nbsp;예&amp;nbsp;)&amp;nbsp;5MB&amp;nbsp;-&amp;nbsp;5*1024*1024 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;FILE_SIZE_LIMIT&amp;nbsp;=&amp;nbsp;5242880 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;허용하는&amp;nbsp;확장자는&amp;nbsp;화이트리스트로&amp;nbsp;관리한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;WHITE_LIST_EXT&amp;nbsp;=&amp;nbsp;[ &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'.jpg', &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;'.jpeg' &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;]&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;file_upload(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;파일&amp;nbsp;개수&amp;nbsp;제한 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;len(request.FILES)&amp;nbsp;==&amp;nbsp;0&amp;nbsp;or&amp;nbsp;len(request.FILES)&amp;nbsp;&amp;gt;&amp;nbsp;FILE_COUNT_LIMIT:&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':&amp;nbsp;'파일&amp;nbsp;개수&amp;nbsp;초과'})&lt;br /&gt;&lt;br /&gt;for&amp;nbsp;filename,&amp;nbsp;upload_file&amp;nbsp;in&amp;nbsp;request.FILES.items(): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;파일&amp;nbsp;타입&amp;nbsp;체크&lt;br /&gt;if&amp;nbsp;upload_file.content_type&amp;nbsp;!=&amp;nbsp;'image/jpeg': &lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':&amp;nbsp;'파일&amp;nbsp;타입&amp;nbsp;오류'}) &lt;/span&gt;&lt;br /&gt;#&amp;nbsp;파일&amp;nbsp;크기&amp;nbsp;제한 &lt;br /&gt;if&amp;nbsp;upload_file.size&amp;nbsp;&amp;gt;&amp;nbsp;FILE_SIZE_LIMIT: &lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':&amp;nbsp;'파일사이즈&amp;nbsp;오류'}) &lt;/span&gt;&lt;br /&gt;#&amp;nbsp;파일&amp;nbsp;확장자&amp;nbsp;검사 &lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;file_name,&amp;nbsp;file_ext&amp;nbsp;=&amp;nbsp;os.path.splitext(upload_file.name) &lt;/span&gt;&lt;br /&gt;if&amp;nbsp;file_ext.lower()&amp;nbsp;not&amp;nbsp;in&amp;nbsp;WHITE_LIST_EXT: &lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':&amp;nbsp;'파일&amp;nbsp;타입&amp;nbsp;오류'})&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;fs&amp;nbsp;=&amp;nbsp;FileSystemStorage(location='media/screenshot',&amp;nbsp;base_url&amp;nbsp;=&amp;nbsp;'media/screenshot') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;for&amp;nbsp;upload_file&amp;nbsp;in&amp;nbsp;request.FILES.values(): &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;fs.save(upload_file.name,&amp;nbsp;upload_file)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'filename':&amp;nbsp;filename})&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQLite DB-API 사용에서도 동일하게 정적인 쿼리문을 사전에 생성하고 사용자 입력을 바인딩 하여 안전하게 사용하여야 한다. SQLite에서 매개변수 화된 쿼리(Parameterized Query)를 만들기 위해 &amp;ldquo;?&amp;rdquo;를 Placeholder로 사용하거나 &amp;ldquo;:name&amp;rdquo; 처럼&amp;nbsp;Named&amp;nbsp;Placeholder를&amp;nbsp;사용하는&amp;nbsp;방법&amp;nbsp;2가지가&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ ORM&amp;nbsp;사용&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django의 querysets는 쿼리 매개변수화를 사용하여 쿼리를 구성하기 때문에 SQL 삽입 공격으로부터 보호된다. 부득이 하게 원시 SQL, 또는 사용자 정의 SQL을 사용할 경우에도 외부 입력값을 매개변수화된 쿼리의 바인딩 변수로 사용하여야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;아래는 Django의 원시 SQL을 사용하는 예제이다. Django의 ORM 프레임워크는 원시 SQL 쿼리를 수행하기 위해 Manager.raw() 기능을 제공한다. 다음은 안전하지 않은 코드로 6라인에서 입력받은 외부 입력값을 10라인의 쿼리문 생성에 문자열 조합으로 사용하여 쿼리문의&amp;nbsp;구조를&amp;nbsp;만들고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from django.shortcuts import render &lt;br /&gt;from&amp;nbsp;app.models&amp;nbsp;import&amp;nbsp;Member&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;member_search(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;가져온다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;받은&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;쿼리문&amp;nbsp;생성에&amp;nbsp;사용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;# 안전하지 않다.&lt;/span&gt;&lt;br /&gt;query=&amp;ldquo;select&amp;nbsp;*&amp;nbsp;from&amp;nbsp;member&amp;nbsp;where&amp;nbsp;name=&amp;lsquo;&amp;rdquo;&amp;nbsp;+&amp;nbsp;name&amp;nbsp;+&amp;nbsp;&amp;ldquo;&amp;rsquo;&amp;rdquo;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용한&amp;nbsp;쿼리문을&amp;nbsp;raw()함수로&amp;nbsp;실행하면 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않다.&lt;/span&gt; &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;Member.objects.raw(query)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/member_list.html',&amp;nbsp;{'member_list':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 코드 예제로 Django에서 원시코드를 실행할 경우에도 매개변수화된 쿼리를 사용하고 params 인수를 사용하여&amp;nbsp;raw()&amp;nbsp;함수의&amp;nbsp;바인딩&amp;nbsp;변수로&amp;nbsp;사용하여야&amp;nbsp;한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;9라인에서 쿼리문 생성을 매개변수화된 쿼리로 생성하고 6라인에서 입력받은&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;10라인의&amp;nbsp;raw()메소드에서&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;인자의&amp;nbsp;바인딩변수로&amp;nbsp;사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;app.models&amp;nbsp;import&amp;nbsp;Member&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;member_search(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;가져온다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;raw()함수&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;바인딩&amp;nbsp;변수로&amp;nbsp;사용하여&amp;nbsp;쿼리&amp;nbsp;구조가 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;변경되지&amp;nbsp;않도록&amp;nbsp;한다.(list&amp;nbsp;형은&amp;nbsp;%s,&amp;nbsp;dictionary&amp;nbsp;형은&amp;nbsp;%(key)s를&amp;nbsp;사용) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;query='select&amp;nbsp;*&amp;nbsp;from&amp;nbsp;member&amp;nbsp;where&amp;nbsp;name=%s'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;인자화된&amp;nbsp;쿼리문을&amp;nbsp;사용하여&amp;nbsp;raw()함수를&amp;nbsp;사용하여&amp;nbsp;안전하다.&lt;/span&gt; &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;Member.objects.raw(query,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;[name]&lt;/span&gt;) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/member_list.html',&amp;nbsp;{'member_list':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <category>시큐어 코딩</category>
      <category>시큐어코딩</category>
      <category>시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/29</guid>
      <comments>https://fathersit.tistory.com/29#entry29comment</comments>
      <pubDate>Wed, 10 Aug 2022 00:35:09 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] HTTP 응답분할</title>
      <link>https://fathersit.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byOZO2/btrJgcbJ26a/Nzpv72c0LX96qpeayDEEp1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byOZO2/btrJgcbJ26a/Nzpv72c0LX96qpeayDEEp1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byOZO2/btrJgcbJ26a/Nzpv72c0LX96qpeayDEEp1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyOZO2%2FbtrJgcbJ26a%2FNzpv72c0LX96qpeayDEEp1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;HTTP 응답분할&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;HTTP 요청에 들어 있는 파라미터(Parameter)가 HTTP 응답헤더에 포함되어 사용자에게 다시 전달될 때, 입력값에 CR(CarriageReturn)이나 LF(LineFeed)와 같은 개행문자가 존재하면 HTTP 응답이 2개 이상으로 분리될 수 있다. 이 경우 공격자는 개행문자를 이용하여 첫 번째 응답을 종료 시키고, 두 번째 응답에 악의적인 코드를 주입하여 XSS 및 캐시훼손(CachePoisoning)&amp;nbsp;공격&amp;nbsp;등을&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python 3.9.5+ 버전에서의 URLValidator에서 HTTP 응답분할 취약점이 보고되기도 했고 해당 라이브러리를 사용하는 Django버전에도 영향이 있다. HTTP 응답분할 공격으로부터 어플리케이션을 안전하게 지키려면 최신 버전의 라이브러리, 프레임&amp;nbsp;워크를&amp;nbsp;사용하고&amp;nbsp;외부&amp;nbsp;입력값에&amp;nbsp;대해서는&amp;nbsp;철저한&amp;nbsp;검증&amp;nbsp;작업을&amp;nbsp;수행해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;요청 파라미터의 값을 HTTP 응답헤더(예를 들어, Set-Cookie 등)에 포함시킬 경우 CR(\r), LF(\n)와 같은 개행문자를 제거한다. 외부 입력값이 헤더, 쿠키, 로그등에 사용될 경우에는 항상 개행 문자를 검증하고 헤더에 사용되는 예약어 등은 화이트리스트로&amp;nbsp;제한&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있으면&amp;nbsp;화이트리스트로&amp;nbsp;제한하여야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자 요청에 포함된 값을 필터링 및 검증 없이 응답에 사용하는 경우 개행문자로 인해 여러 개의 응답으로 분할되어 사용자에게&amp;nbsp;전달될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.http&amp;nbsp;import&amp;nbsp;HttpResponse&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;route(request): &lt;br /&gt;content_type&amp;nbsp;=&amp;nbsp;request.POST.get('contnet-type') &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;검증&amp;nbsp;또는&amp;nbsp;필터링&amp;nbsp;하지&amp;nbsp;않고 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;응답헤더의&amp;nbsp;값으로&amp;nbsp;포함시켜&amp;nbsp;회신한다.&lt;/span&gt; &lt;br /&gt;...... &lt;br /&gt;res&amp;nbsp;=&amp;nbsp;HttpResponse() &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;res['Content-Type']&amp;nbsp;=&amp;nbsp;content_type&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;res&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응답 분할을 예방하기 위해 \r, \n과 같은 문자에 대해서 치환 또는 예외처리 하여 응답분할이 발생하지 않도록 예방하여야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.http&amp;nbsp;import&amp;nbsp;HttpResponse&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;route(request): &lt;br /&gt;content_type&amp;nbsp;=&amp;nbsp;request.POST.get('contnet-type')&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;응답헤더에&amp;nbsp;포함될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;외부&amp;nbsp;입력값에&amp;nbsp;대해&amp;nbsp;개행문자를&amp;nbsp;제거한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;content_type&amp;nbsp;=&amp;nbsp;content_type.replace('\r',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;content_type&amp;nbsp;=&amp;nbsp;content_type.replace('\n',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;...... &lt;br /&gt;res&amp;nbsp;=&amp;nbsp;HttpResponse() &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;res['Content-Type']&amp;nbsp;=&amp;nbsp;content_type&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;res&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/27</guid>
      <comments>https://fathersit.tistory.com/27#entry27comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:50:03 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] Private 배열에 Public 데이터 할당</title>
      <link>https://fathersit.tistory.com/26</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bghhak/btrJcFMWfSs/wTZg6kkdkfG0TRfcSZt7Fk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bghhak/btrJcFMWfSs/wTZg6kkdkfG0TRfcSZt7Fk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bghhak/btrJcFMWfSs/wTZg6kkdkfG0TRfcSZt7Fk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbghhak%2FbtrJcFMWfSs%2FwTZg6kkdkfG0TRfcSZt7Fk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 캡슐화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안약점으로 정보노출, 권한 문제 등이 발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Private 배열에 Public 데이터 할당&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;public으로 선언된 메소드의 인자가 private 선언된 배열에 저장되면, private 배열을 외부에서 접근하여 배열 수정과 객체 속성&amp;nbsp;변경이&amp;nbsp;가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;public으로 선언된 메소드의 인자를 private선언된 배열로 저장되지 않도록 한다. 인자로 들어온 배열의 복사본을 생성하고 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private 배열에 할당하여 private 선언된 배열과 객체속성에 대한 의도하지&amp;nbsp;않게&amp;nbsp;수정되는&amp;nbsp;것을&amp;nbsp;방지한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;만약 배열 객체의 원소가 String 타입 등과 같이 변경이 되지 않는 경우에는 인자로 들어온 배열의&amp;nbsp;복사본을&amp;nbsp;생성하여&amp;nbsp;할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 __를 이용해서 Python의 내부 배열을 생성하고 외부 값을 대입하는 public 메소드를 사용하고 있다. 이 경우 특정&amp;nbsp;배열&amp;nbsp;타입에&amp;nbsp;따라&amp;nbsp;외부에서&amp;nbsp;private&amp;nbsp;배열을&amp;nbsp;변조할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문제를&amp;nbsp;내포하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;copy &lt;br /&gt;class&amp;nbsp;UserObj(): &lt;br /&gt;__private_variable&amp;nbsp;=&amp;nbsp;[] &lt;br /&gt;def&amp;nbsp;__init__(self): &lt;br /&gt;pass&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;private&amp;nbsp;배열에&amp;nbsp;외부&amp;nbsp;값을&amp;nbsp;바로&amp;nbsp;대입하는&amp;nbsp;public&amp;nbsp;메소드를&amp;nbsp;사용하는 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;경우&amp;nbsp;취약함&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;set_private_member(self,&amp;nbsp;num): &lt;br /&gt;self.__private_variable&amp;nbsp;=&amp;nbsp;num&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래&amp;nbsp;예제는&amp;nbsp;내부와&amp;nbsp;외부의&amp;nbsp;배열이&amp;nbsp;서로&amp;nbsp;참조되는&amp;nbsp;것을&amp;nbsp;예방하기&amp;nbsp;위해&amp;nbsp;[:]로&amp;nbsp;새로운&amp;nbsp;객체를&amp;nbsp;생성하여&amp;nbsp;값을&amp;nbsp;대입하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;class&amp;nbsp;UserObj(): &lt;br /&gt;def&amp;nbsp;__init__(self): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;self.__privateVariable&amp;nbsp;=&amp;nbsp;[]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;private&amp;nbsp;배열에&amp;nbsp;외부&amp;nbsp;값을&amp;nbsp;바로&amp;nbsp;대입하는&amp;nbsp;경우&amp;nbsp;[:]를&amp;nbsp;사용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부와&amp;nbsp;내부의&amp;nbsp;배열이&amp;nbsp;서로&amp;nbsp;참조되지&amp;nbsp;않도록&amp;nbsp;해야&amp;nbsp;함&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;set_private_member(self,&amp;nbsp;num): &lt;br /&gt;self.__privateVariable&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;num[:]&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/26</guid>
      <comments>https://fathersit.tistory.com/26#entry26comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:35:25 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 운영체제 명령어 삽입</title>
      <link>https://fathersit.tistory.com/25</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pXJdD/btrJfYkF7Oa/YWt59sUvdEkbBXhuvjiHQK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pXJdD/btrJfYkF7Oa/YWt59sUvdEkbBXhuvjiHQK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pXJdD/btrJfYkF7Oa/YWt59sUvdEkbBXhuvjiHQK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpXJdD%2FbtrJfYkF7Oa%2FYWt59sUvdEkbBXhuvjiHQK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;운영체제 명령어 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;적절한 검증절차를 거치지 않은 사용자 입력값이 운영체제 명령어의 일부 또는 전부로 구성되어 실행되는 경우, 의도하지 않은&amp;nbsp;시스템&amp;nbsp;명령어가&amp;nbsp;실행되어&amp;nbsp;부적절하게&amp;nbsp;권한이&amp;nbsp;변경되거나&amp;nbsp;시스템&amp;nbsp;동작&amp;nbsp;및&amp;nbsp;운영에&amp;nbsp;악영향을&amp;nbsp;미칠&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;일반적으로 명령어 라인의 파라미터나 스트림 입력 등 외부 입력을 사용하여 시스템 명령어를 생성 하는 프로그램이 많이 있다. 하지만 이러한 경우 외부 입력 문자열은 신뢰할 수 없기 때문에 적절한 처리를 해주지 않으면, 공격자가 원하는 명령어 실행이&amp;nbsp;가능하게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파이썬에서 eval() 함수와 exec() 함수는 내부에서 문자열을 실행하기에 편리하지만, String 형식의 표현된 식을 인수로 받아 반환하는 eval() 함수와 인수로 받은 문자열을 실행하는 exec()를 같이 사용하면 여러 변수들에 동적으로 값을 할당하여 사용될&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;Command&amp;nbsp;Injection&amp;nbsp;공격에&amp;nbsp;취약하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부 입력값이 시스템 명령에 포함되는 경우 |, ;, &amp;amp;, :, &amp;gt;, &amp;lt;, `(backtick), \, ! 과 같이 멀티라인 파이프 리다이렉트 문자 등을 필터링 하고 명령을 수행할 파일명, 옵션을 제한하여 인자로만 사용될 수 있도록 한다. 외부 입력에 따라 명령어를 생성하거나&amp;nbsp;선택이&amp;nbsp;필요한&amp;nbsp;경우에는&amp;nbsp;명령어&amp;nbsp;생성에&amp;nbsp;필요한&amp;nbsp;값&amp;nbsp;들을&amp;nbsp;미리&amp;nbsp;지정해&amp;nbsp;놓고&amp;nbsp;외부&amp;nbsp;입력에&amp;nbsp;따라&amp;nbsp;선택하여&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 os.system을 이용하여 외부 입력 받은 값을 통해 프로그램을 실행하며, 외부에서 전달되는 인자 값은 명령어의 생성에 사용된다. 그러나 해당 프로그램에서 실행할 프로그램을 제한하지 않고 있기 때문에 외부의 공격자는 가능한 모든 프로그램을&amp;nbsp;실행시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import os&lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;execute_command(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;app_name_string&amp;nbsp;=&amp;nbsp;request.POST.get('app_name','') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;입력받은&amp;nbsp;파라미터를&amp;nbsp;제한하지&amp;nbsp;않아&amp;nbsp;외부&amp;nbsp;입력값으로&amp;nbsp;전달된 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;모든&amp;nbsp;프로그램이&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있음 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;os.system(app_name_string)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부에서 입력 받은 값이 명령어의 인자로 사용되지 않고 명령어로 사용될 경우에는 미리 화이트리스트의 정의된 파라미터 배열을 만들어 놓고, 외부의 입력에 따라 적절한 파라미터를 선택하도록 하여, 외부의 부적절한 입력이 명령어로 사용될 가능성을 배제하여야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;os &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ALLOW_PROGRAM&amp;nbsp;=&amp;nbsp;['notepad',&amp;nbsp;'calc']&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;execute_command(request): &lt;br /&gt;app_name_string&amp;nbsp;=&amp;nbsp;request.POST.get('app_name','')&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;입력받은&amp;nbsp;파라미터를&amp;nbsp;사용가능한&amp;nbsp;시스템&amp;nbsp;명령어&amp;nbsp;일부로&amp;nbsp;제한하여&amp;nbsp;사용 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;app_name_string&amp;nbsp;not&amp;nbsp;in&amp;nbsp;ALLOW_PROGRAM:&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'ERROR':'허용되지&amp;nbsp;않은&amp;nbsp;프로그램입니다.'})&lt;br /&gt;&lt;br /&gt;os.system(app_name_string) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 subprocess()함수를 사용하여 별도의 프로세스로 응용프로그램을 실행하는 경우의 안전하지 않은 예제이다. 외부 입력값으로&amp;nbsp;받은&amp;nbsp;파라미터를&amp;nbsp;별도의&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;subprocess의&amp;nbsp;인자&amp;nbsp;값으로&amp;nbsp;사용하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;subprocess &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;execute_command(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;date&amp;nbsp;=&amp;nbsp;request.POST.get('date','') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;입력받은&amp;nbsp;파라미터를&amp;nbsp;제한하지&amp;nbsp;않아&amp;nbsp;전달된&amp;nbsp;모든&amp;nbsp;프로그램이 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있음&lt;/span&gt; &lt;br /&gt;cmd_str&amp;nbsp;=&amp;nbsp;&amp;ldquo;cmd&amp;nbsp;/c&amp;nbsp;backuplog.bat&amp;nbsp;&amp;rdquo;&amp;nbsp;+&amp;nbsp;date &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;subprocess.run(cmd_str,&amp;nbsp;shell=True)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;운영체제 명령어 실행 시에는 아래와 같이 외부에서 들어오는 값에 의하여 멀티라인을 지원하는 특수문자(|, ;, &amp;amp;, :, `, \, !)나 파일&amp;nbsp;리다이렉트&amp;nbsp;특수문자(&amp;nbsp;&amp;gt;,&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;)등을&amp;nbsp;제거하여&amp;nbsp;원하지&amp;nbsp;않는&amp;nbsp;운영체제&amp;nbsp;명령어가&amp;nbsp;실행&amp;nbsp;될&amp;nbsp;수&amp;nbsp;없도록&amp;nbsp;필터링을&amp;nbsp;수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Command lines을 구문 분석하고 escape하는 기능을 제공하는 모듈인 shlex 모듈을 사용하여 필터링을 수행한다. subprocess의 옵션 값 중 shell=True 일 경우 중간 프로세스에 의해 명령이 실행되고 파일 이름, 와일드카드(*), 환경변수 확장 등의 쉘 기능을 검증 없이 실행하게 되므로 shell의 옵션은 삭제한다. (default 값은 False)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;subprocess &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;execute_command(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;date&amp;nbsp;=&amp;nbsp;request.POST.get('date','')&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;명령어를&amp;nbsp;추가로&amp;nbsp;실행&amp;nbsp;또는&amp;nbsp;다른&amp;nbsp;명령이&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;키워드에 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;대한&amp;nbsp;예외처리 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;for&amp;nbsp;word&amp;nbsp;in&amp;nbsp;['|',&amp;nbsp;';',&amp;nbsp;'&amp;amp;',&amp;nbsp;':',&amp;nbsp;'&amp;gt;',&amp;nbsp;'&amp;lt;',&amp;nbsp;'`',&amp;nbsp;'\\',&amp;nbsp;'!']: &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;date&amp;nbsp;=&amp;nbsp;date.replace(word,&amp;nbsp;&amp;ldquo;&amp;rdquo;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;shell=True&amp;nbsp;옵션은&amp;nbsp;제거&amp;nbsp;하고&amp;nbsp;명령과&amp;nbsp;인자를&amp;nbsp;배열로&amp;nbsp;입력 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;subprocess.run([&quot;cmd&quot;,&amp;nbsp;&quot;/c&quot;,&amp;nbsp;&quot;backuplog.bat&quot;,&amp;nbsp;date])&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;re.sub함수를&amp;nbsp;사용하여&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;특수문자를&amp;nbsp;제거할&amp;nbsp;수도&amp;nbsp;있다. &lt;br /&gt;※&amp;nbsp;date&amp;nbsp;=&amp;nbsp;re.sub('[|;&amp;amp;:&amp;gt;&amp;lt;`\\\!]',&amp;nbsp;'',&amp;nbsp;date)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/25</guid>
      <comments>https://fathersit.tistory.com/25#entry25comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:27:00 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 솔트 없이 일방향 해쉬 함수 사용</title>
      <link>https://fathersit.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8wvXF/btrJhiW3he1/ZRONtgsLgAK9OH1kvuMP0k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8wvXF/btrJhiW3he1/ZRONtgsLgAK9OH1kvuMP0k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8wvXF/btrJhiW3he1/ZRONtgsLgAK9OH1kvuMP0k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8wvXF%2FbtrJhiW3he1%2FZRONtgsLgAK9OH1kvuMP0k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;솔트 없이 일방향 해쉬 함수 사용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드와 같은 중요정보를 저장할 경우, 임의의 길이인 데이터를 고정된 크기의 해쉬값으로 변환해주는 일방향 해쉬함수를 이용하여 저장한다. 만약 중요정보를 솔트(Salt)없이 일방향 해쉬함수를 사용하여 저장한다면, 공격자는 미리 계산된 레인보우 테이블을&amp;nbsp;이용하여&amp;nbsp;해쉬값을&amp;nbsp;알아낼&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드와 같은 중요정보를 저장할 경우, 임의의 길이인 데이터를 고정된 크기의 해쉬값으로 변환해주는 일방향 해쉬함수를 이용하여&amp;nbsp;저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서 hashlib라이브러리를 사용해서 Hash값을 생성 할 수 있고, salt 값은 os.urandom()등 안전한 난수 생성 라이브러리를&amp;nbsp;사용하여&amp;nbsp;생성해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 예시와 같은 코드는 비밀번호와 같은 값을 해쉬하고 있는데 원문의 길이가 짧기 때문에 공격자에 의해 쉽게 유추될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;hashlib&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_hash_from_pwd(pw): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;salt가&amp;nbsp;없이&amp;nbsp;생성된&amp;nbsp;해시값은&amp;nbsp;강도가&amp;nbsp;약하기&amp;nbsp;때문에&amp;nbsp;반드시&amp;nbsp;salt와&amp;nbsp;함께 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;생성해야&amp;nbsp;한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;h&amp;nbsp;=&amp;nbsp;hashlib.sha256(pw.encode())&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;h.digest()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;짧은&amp;nbsp;길이의&amp;nbsp;비밀번호를&amp;nbsp;이용하여&amp;nbsp;강도&amp;nbsp;높은&amp;nbsp;해쉬값을&amp;nbsp;생성하기&amp;nbsp;위해서는&amp;nbsp;반드시&amp;nbsp;seed&amp;nbsp;값과&amp;nbsp;함께&amp;nbsp;해쉬를&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;hashlib &lt;br /&gt;import&amp;nbsp;secrets&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_hash_from_pwd(pw): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;비밀번호와&amp;nbsp;같이&amp;nbsp;길이가&amp;nbsp;짧은&amp;nbsp;값을&amp;nbsp;이용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;고강도의&amp;nbsp;해시를&amp;nbsp;생성하기&amp;nbsp;위해서는&amp;nbsp;salt값을 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용하면&amp;nbsp;강도높은&amp;nbsp;해시를&amp;nbsp;생성할&amp;nbsp;수&amp;nbsp;있다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;salt&amp;nbsp;=&amp;nbsp;secrets.token_hex(32) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;h&amp;nbsp;=&amp;nbsp;hashlib.sha256(salt.encode()&amp;nbsp;+&amp;nbsp;pw.encode())&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;h.digest(),&amp;nbsp;salt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/24</guid>
      <comments>https://fathersit.tistory.com/24#entry24comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:11:36 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 포맷 스트링 삽입</title>
      <link>https://fathersit.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFKzib/btrJcGE1H0j/YGsl2MHA2Xy0TqGZpB1Kt0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFKzib/btrJcGE1H0j/YGsl2MHA2Xy0TqGZpB1Kt0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFKzib/btrJcGE1H0j/YGsl2MHA2Xy0TqGZpB1Kt0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFKzib%2FbtrJcGE1H0j%2FYGsl2MHA2Xy0TqGZpB1Kt0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;포맷 스트링 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부로부터 입력된 값을 검증하지 않고 입&amp;middot;출력 함수의 포맷 문자열로 그대로 사용하는 경우 발생할 수 있는 보안약점이다. 공격자는 포맷 문자열을 이용하여 취약한 프로세스를 공격하거나 메모리 내용을 읽거나 쓸 수 있다. 그 결과, 공격자는 취약한 프로세스의&amp;nbsp;권한을&amp;nbsp;취득하여&amp;nbsp;임의의&amp;nbsp;코드를&amp;nbsp;실행&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서는 문자열의 포맷팅 방법으로 &amp;ldquo;% formatting&amp;rdquo;, &amp;ldquo;str.format&amp;rdquo;, &amp;ldquo;f-string&amp;rdquo; 3가지 방법의 문자열 포맷팅 형식을 제공하고 있다. f-string 방법은 Python 3.6부터 도입된 포맷팅 방법이다. 공격자는 포맷 문자열을 이용하여 내부 정보를 문자열로&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;이를&amp;nbsp;반환하는&amp;nbsp;경우&amp;nbsp;내부의&amp;nbsp;중요&amp;nbsp;정보가&amp;nbsp;유출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;포맷 문자열을 사용하는 함수를 사용할 때는 사용자 입력 값을 직접적으로 포맷 문자열로 사용하거나 포맷 문자열 생성에 포함시키지 않아야 한다. 사용자에게 입력받은 데이터를 포맷 문자열로 사용하고자 하는 경우에는 서식지정자를 포함하지 않거나&amp;nbsp;파이썬의&amp;nbsp;내장함수&amp;nbsp;또는&amp;nbsp;내장변수&amp;nbsp;등이&amp;nbsp;포함되지&amp;nbsp;않도록&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 예시에서는 외부에서 입력받은 문자열을 바로 포맷스트링으로 사용하고 있는데 이는 내부 정보가 외부로 노출될 수 있는&amp;nbsp;문제를&amp;nbsp;내포하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;공격자가 # {user.__init__.__globals__[AUTHENTICATE_KEY]} 형식의 문자열 입력 시 글로벌 변수에 접근하여 AUTHENTICATE_KEY의&amp;nbsp;값을&amp;nbsp;탈취&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;AUTHENTICATE_KEY&amp;nbsp;=&amp;nbsp;'Passw0rd'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;make_user_message(request): &lt;br /&gt;user_info&amp;nbsp;=&amp;nbsp;get_user_info(request.POST.get('user_id',&amp;nbsp;''))&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;format_string&amp;nbsp;=&amp;nbsp;request.POST.get('msg_format',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;내부의&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;외부로&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자가&amp;nbsp;입력한&amp;nbsp;문자열을&amp;nbsp;포맷&amp;nbsp;문자열로&amp;nbsp;사용하고&amp;nbsp;있어&amp;nbsp;안전하지&amp;nbsp;않다&lt;/span&gt; &lt;br /&gt;message&amp;nbsp;=&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;format_string.format&lt;/span&gt;(user=user_info)&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/user_page',&amp;nbsp;{'message':message})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부에서 입력받은 문자열은 반드시 포맷지정자를 이용하여 바인딩하여 사용하여야 하며 직접적으로 포맷문자열로 사용해서는&amp;nbsp;안&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;AUTHENTICATE_KEY&amp;nbsp;=&amp;nbsp;'Passw0rd'&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;make_user_message(request): &lt;br /&gt;user_info&amp;nbsp;=&amp;nbsp;get_user_info(request.POST.get('user_id',&amp;nbsp;''))&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;사용자가&amp;nbsp;입력한&amp;nbsp;문자열을&amp;nbsp;포맷&amp;nbsp;문자열로&amp;nbsp;사용하지&amp;nbsp;않아&amp;nbsp;안전하다 &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;message&amp;nbsp;=&amp;nbsp;'user&amp;nbsp;name&amp;nbsp;is&amp;nbsp;{}'.format(user_info.name)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/user_page',&amp;nbsp;{'message':message})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/23</guid>
      <comments>https://fathersit.tistory.com/23#entry23comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:06:22 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 경로 조작 및 자원 삽입</title>
      <link>https://fathersit.tistory.com/22</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpAR8j/btrJgbX9Dix/2fY71bubyXQuX04Rjn1FZ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpAR8j/btrJgbX9Dix/2fY71bubyXQuX04Rjn1FZ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpAR8j/btrJgbX9Dix/2fY71bubyXQuX04Rjn1FZ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpAR8j%2FbtrJgbX9Dix%2F2fY71bubyXQuX04Rjn1FZ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;경로 조작 및 자원 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;검증되지 않은 외부 입력값을 통해 파일 및 서버 등 시스템 자원(파일, 소켓의 포트 등)에 대한 접근 혹은 식별을 허용할 경우, 입력 값 조작을 통해 시스템이 보호하는 자원에 임의로 접근할 수 있는 보안약점이다. 경로조작 및 자원삽입 약점을 이용하여&amp;nbsp;공격자는&amp;nbsp;자원의&amp;nbsp;수정&amp;middot;삭제,&amp;nbsp;시스템&amp;nbsp;정보누출,&amp;nbsp;시스템&amp;nbsp;자원&amp;nbsp;간&amp;nbsp;충돌로&amp;nbsp;인한&amp;nbsp;서비스&amp;nbsp;장애&amp;nbsp;등을&amp;nbsp;유발시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;즉, 경로 조작 및 자원 삽입을 통해서 공격자가 허용되지 않은 권한을 획득하여, 설정에 관계된 파일을 변경하거나 실행시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서는 subprocess.popen()과 같이 프로세스를 여는 함수, os.pipe()처럼 파이프를 여는 함수 , socket 연결 등에서&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;경로&amp;nbsp;조작&amp;nbsp;및&amp;nbsp;자원&amp;nbsp;삽입의&amp;nbsp;취약점이&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부의 입력 값을 자원(파일, 소켓의 포트 등)의 식별자로 사용하는 경우, 적절한 검증을 거치도록 하거나, 사전에 정의된 리스트에서 선택되도록 한다. 특히, 외부의 입력이 파일명인 경우에는 경로순회 directory traversal) 공격의 위험이 있는 문자 (&amp;nbsp;/,&amp;nbsp;\,&amp;nbsp;..&amp;nbsp;등)를&amp;nbsp;제거할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;필터를&amp;nbsp;이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 경로&amp;nbsp;조작&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;6라인에서 외부 입력값으로 파일 경로 등을 입력받아 14라인에서 파일을 오픈하고 있다. 만약 공격자가 ../../../../etc/passwd와 같은 값을 전달하면 의도하지 않았던 파일의 내용이 클라이언트 측에 표시되어 시스템 정보노출 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;os &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_info(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;파일명을&amp;nbsp;입력받고&amp;nbsp;있다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;request_file&amp;nbsp;=&amp;nbsp;request.POST.get('request_file') &lt;/span&gt;&lt;br /&gt;filename,&amp;nbsp;file_ext&amp;nbsp;=&amp;nbsp;os.path.splitext(request_file) &lt;br /&gt;file_ext&amp;nbsp;=&amp;nbsp;file_ext.lower()&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;file_ext&amp;nbsp;not&amp;nbsp;in&amp;nbsp;['.txt',&amp;nbsp;'.csv']: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'파일을&amp;nbsp;열수&amp;nbsp;없습니다.'})&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력받은&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;파일&amp;nbsp;처리에&amp;nbsp;사용하였다.&lt;/span&gt; &lt;br /&gt;with&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;open(request_file)&lt;/span&gt;&amp;nbsp;as&amp;nbsp;f: &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;f.read()&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'data':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부&amp;nbsp;입력값에서&amp;nbsp;경로&amp;nbsp;조작&amp;nbsp;문자열&amp;nbsp;(&amp;nbsp;/,&amp;nbsp;\,&amp;nbsp;..&amp;nbsp;등)을&amp;nbsp;제거한&amp;nbsp;후&amp;nbsp;파일의&amp;nbsp;경로설정에&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;os &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_info(request): &lt;br /&gt;#&amp;nbsp;외부&amp;nbsp;입력&amp;nbsp;값으로&amp;nbsp;받은&amp;nbsp;파일&amp;nbsp;이름은&amp;nbsp;검증하여&amp;nbsp;사용한다. &lt;br /&gt;request_file&amp;nbsp;=&amp;nbsp;request.POST.get('request_file')&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;filename&lt;/span&gt;,&amp;nbsp;file_ext&amp;nbsp;=&amp;nbsp;os.path.splitext(request_file) &lt;br /&gt;file_ext&amp;nbsp;=&amp;nbsp;file_ext.lower()&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;file_ext&amp;nbsp;not&amp;nbsp;in&amp;nbsp;['.txt',&amp;nbsp;'.csv']: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'파일을&amp;nbsp;열수&amp;nbsp;없습니다.'})&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;파일&amp;nbsp;명에서&amp;nbsp;경로&amp;nbsp;조작&amp;nbsp;문자열을&amp;nbsp;필터링&amp;nbsp;한다. &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;filename&amp;nbsp;=&amp;nbsp;filename.replace('.',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;filename&amp;nbsp;=&amp;nbsp;filename.replace('/',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;filename&amp;nbsp;=&amp;nbsp;filename.replace('\\',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;open(filename&amp;nbsp;+&amp;nbsp;file_ext)&amp;nbsp;as&amp;nbsp;f: &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;f.read()&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'data':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;relplace&amp;nbsp;함수&amp;nbsp;외에도&amp;nbsp;re.sub,&amp;nbsp;filter&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;특수문자를&amp;nbsp;필터링&amp;nbsp;하는&amp;nbsp;것도&amp;nbsp;가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 자원&amp;nbsp;삽입&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음의 예제는 안전하지 않은 코드의 예로, 외부의 입력을 소켓 포트번호로 그대로 사용하고 있다. 외부 입력값을 검증없이 사용할&amp;nbsp;경우&amp;nbsp;기존&amp;nbsp;자원과&amp;nbsp;충돌로&amp;nbsp;에러가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;socket &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_info(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;port&amp;nbsp;=&amp;nbsp;request.POST.get('port')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;socket.socket(socket.AF_INET,&amp;nbsp;socket.SOCK_STREAM)&amp;nbsp;as&amp;nbsp;s: &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력받은&amp;nbsp;검증되지&amp;nbsp;않은&amp;nbsp;포트번호를&amp;nbsp;이용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;소켓을&amp;nbsp;바인딩&amp;nbsp;하여&amp;nbsp;사용하고&amp;nbsp;있어&amp;nbsp;안전하지&amp;nbsp;않다.&lt;/span&gt; &lt;br /&gt;s.bind(('127.0.0.1',&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;port&lt;/span&gt;)) &lt;br /&gt;... &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success')&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error',&amp;nbsp;{'error':'소켓연결&amp;nbsp;실패'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 예제를 나타낸 것이다. 내부자원에 접근할 때 외부에서 입력 받은 값을 포트번호와 같은 식별자로 그대로 사용하는&amp;nbsp;것은&amp;nbsp;바람직하지&amp;nbsp;않으며,&amp;nbsp;꼭&amp;nbsp;필요한&amp;nbsp;경우엔&amp;nbsp;가능한&amp;nbsp;리스트를&amp;nbsp;설정하고,&amp;nbsp;해당&amp;nbsp;범위&amp;nbsp;내에서&amp;nbsp;할당되도록&amp;nbsp;작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;socket &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ALLOW_PORT&amp;nbsp;=&amp;nbsp;[4000,&amp;nbsp;6000,&amp;nbsp;9000]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_info(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;port&amp;nbsp;=&amp;nbsp;int(request.POST.get('port'))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용&amp;nbsp;가능한&amp;nbsp;포트&amp;nbsp;번호를&amp;nbsp;화이트리스트로&amp;nbsp;제한&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;port&amp;nbsp;not&amp;nbsp;in&amp;nbsp;ALLOW_PORT:&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error',&amp;nbsp;{'error':'소켓연결&amp;nbsp;실패'}) &lt;br /&gt;&lt;br /&gt;with&amp;nbsp;socket.socket(socket.AF_INET,&amp;nbsp;socket.SOCK_STREAM)&amp;nbsp;as&amp;nbsp;s: &lt;br /&gt;s.bind(('127.0.0.1',&amp;nbsp;port)) &lt;br /&gt;...... &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/22</guid>
      <comments>https://fathersit.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 9 Aug 2022 01:02:23 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 부적절한 인가</title>
      <link>https://fathersit.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UcpWh/btrJfZRltIX/RjgaavN21hNYp0M00IJfE0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UcpWh/btrJfZRltIX/RjgaavN21hNYp0M00IJfE0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UcpWh/btrJfZRltIX/RjgaavN21hNYp0M00IJfE0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUcpWh%2FbtrJfZRltIX%2FRjgaavN21hNYp0M00IJfE0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;부적절한 인가&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램이 모든 가능한 실행 경로에 대해서 접근 제어를 검사하지 않거나 불완전하게 검사하는 경우, 공격자는 접근 가능한 실행경로를&amp;nbsp;통해&amp;nbsp;정보를&amp;nbsp;유출할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응용프로그램이 제공하는 정보와 기능을 역할에 따라 배분함으로써 공격자에게 노출되는 공격노출 (Attack Surface)을 최소화하고&amp;nbsp;사용자의&amp;nbsp;권한에&amp;nbsp;따른&amp;nbsp;ACL(Access&amp;nbsp;Control&amp;nbsp;List)을&amp;nbsp;관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자&amp;nbsp;입력&amp;nbsp;값에&amp;nbsp;따라&amp;nbsp;삭제작업을&amp;nbsp;수행하고&amp;nbsp;있으며,&amp;nbsp;사용자의&amp;nbsp;권한&amp;nbsp;확인을&amp;nbsp;위한&amp;nbsp;별도의&amp;nbsp;통제가&amp;nbsp;적용되지&amp;nbsp;않고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;.model&amp;nbsp;import&amp;nbsp;Content&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;delete_content(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;action&amp;nbsp;=&amp;nbsp;request.POST.get('action',&amp;nbsp;'')&lt;/span&gt; &lt;br /&gt;content_id&amp;nbsp;=&amp;nbsp;request.POST.get('content_id',&amp;nbsp;'') &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#작업&amp;nbsp;요청을&amp;nbsp;하는&amp;nbsp;사용자의&amp;nbsp;권한&amp;nbsp;확인&amp;nbsp;없이&amp;nbsp;delete를&amp;nbsp;수행 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;if&amp;nbsp;action&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None&amp;nbsp;and&amp;nbsp;action&amp;nbsp;==&amp;nbsp;&quot;delete&quot;: &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Content.objects.filter(id=content_id).delete()&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html') &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'접근&amp;nbsp;권한이&amp;nbsp;없습니다.'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;세션에 저장된 사용자 정보를 통해 해당 사용자가 수행할 작업에 대한 권한이 있는지 확인한 뒤 권한이 있는 경우에만 수행하도록&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;.model&amp;nbsp;import&amp;nbsp;Content&lt;br /&gt;&lt;br /&gt;@login_required&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;해당&amp;nbsp;기능을&amp;nbsp;수행할&amp;nbsp;권한이&amp;nbsp;있는지&amp;nbsp;확인 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;@permission_required('content.delete',&amp;nbsp;raise_exception=True) &lt;/span&gt;&lt;br /&gt;def&amp;nbsp;delete_content(request): &lt;br /&gt;action&amp;nbsp;=&amp;nbsp;request.POST.get('action',&amp;nbsp;'') &lt;br /&gt;content_id&amp;nbsp;=&amp;nbsp;request.POST.get('content_id',&amp;nbsp;'') &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;action&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None&amp;nbsp;and&amp;nbsp;action&amp;nbsp;==&amp;nbsp;&quot;delete&quot;: &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Content.objects.filter(id=content_id).delete()&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html') &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'삭제&amp;nbsp;실패'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/21</guid>
      <comments>https://fathersit.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:52:55 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 하드코드된 중요정보</title>
      <link>https://fathersit.tistory.com/20</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d61ZnQ/btrJilMIGxc/PgVvQBoczklIHB21a7QNgK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d61ZnQ/btrJilMIGxc/PgVvQBoczklIHB21a7QNgK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d61ZnQ/btrJilMIGxc/PgVvQBoczklIHB21a7QNgK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd61ZnQ%2FbtrJilMIGxc%2FPgVvQBoczklIHB21a7QNgK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;하드코드된 중요정보&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 코드 내부에 하드코드된 패스워드를 포함하고, 이를 이용하여 내부 인증에 사용하거나 외부 컴포넌트와 통신을 하는 경우 관리자의 정보가 노출 될 수 있어 위험하다. 또한 하드코드된 암호화 키를 사용하여 암호화를 수행하면 암호화된 정보가 유출될 가능성이 높아진다. 암호키의 해쉬를 계산하여 저장하더라도 역계산이 가능하여 적어도 무차별 공격(Brute-Force)공격에는&amp;nbsp;취약할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드는 암호화 하여 별도의 파일에 저장하여 사용한다. 또한 중요정보를 암호화하면, 상수가 아닌 암호화 키를 사용하도록&amp;nbsp;하며&amp;nbsp;암호화&amp;nbsp;되었더라도&amp;nbsp;소스코드&amp;nbsp;내부에&amp;nbsp;상수&amp;nbsp;형태의&amp;nbsp;암호화&amp;nbsp;키를&amp;nbsp;저장해서&amp;nbsp;사용하지&amp;nbsp;않도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;소스코드에&amp;nbsp;패스워드&amp;nbsp;또는&amp;nbsp;암호화&amp;nbsp;키&amp;nbsp;같은&amp;nbsp;중요&amp;nbsp;정보를&amp;nbsp;하드코딩&amp;nbsp;하는&amp;nbsp;경우,&amp;nbsp;중요정보가&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;위험하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;pymysql &lt;br /&gt;def&amp;nbsp;query_execute(query): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;usre,&amp;nbsp;passwd가&amp;nbsp;소스코드에&amp;nbsp;평문으로&amp;nbsp;하드코딩되어&amp;nbsp;있음&lt;/span&gt; &lt;br /&gt;dbconn&amp;nbsp;=&amp;nbsp;pymysql.connect(&lt;span style=&quot;color: #ee2323;&quot;&gt;host='127.0.0.1', port='1234', user='root', passwd='1234',&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;db='mydb',&amp;nbsp;charset='utf8'&lt;/span&gt;) &lt;br /&gt;curs&amp;nbsp;=&amp;nbsp;dbconn.cursor() &lt;br /&gt;curs.execute(query) &lt;br /&gt;dbconn.commit() &lt;br /&gt;dbconn.close()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드와 같은 중요정보는 안전한 암호화 방식으로 암호화하여 별도의 분리된 공간(파일)에 저장해야 하며, 암호화된 중요정보를&amp;nbsp;사용하기&amp;nbsp;위해서는&amp;nbsp;복호화&amp;nbsp;과정을&amp;nbsp;거쳐야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;pymysql &lt;br /&gt;import&amp;nbsp;json&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;query_execute(query,&amp;nbsp;config_path):&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;open(config_path,&amp;nbsp;'r')&amp;nbsp;as&amp;nbsp;config: &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;설정파일에서&amp;nbsp;user,&amp;nbsp;passwd를&amp;nbsp;가져와&amp;nbsp;사용&lt;/span&gt; &lt;br /&gt;dbconf&amp;nbsp;=&amp;nbsp;json.load(fp=config) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#암호화되어&amp;nbsp;있는&amp;nbsp;블록암호화&amp;nbsp;키를&amp;nbsp;복호화&amp;nbsp;해서&amp;nbsp;가져오는 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#사용자&amp;nbsp;정의&amp;nbsp;함수 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;blockKey&amp;nbsp;=&amp;nbsp;get_decrypt_key('blockKey') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;설정파일에&amp;nbsp;암호화되어&amp;nbsp;있는&amp;nbsp;값을&amp;nbsp;가져와&amp;nbsp;복호화한&amp;nbsp;후에&amp;nbsp;사용 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;dbUser&amp;nbsp;=&amp;nbsp;decrypt(blockKey,&amp;nbsp;dbconf['user']) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;dbPasswd&amp;nbsp;=&amp;nbsp;decrypt(blockKey,&amp;nbsp;dbconf['passwd'])&lt;/span&gt; &lt;br /&gt;dbconn&amp;nbsp;=&amp;nbsp;pymysql.connect(host=dbconf['host'],&amp;nbsp;port=dbconf['port'],&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;user=dbUser, pass&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;wd=dbPasswd,&lt;/span&gt;&amp;nbsp;db=dbconf['db_name'],&amp;nbsp;charset='utf8') &lt;br /&gt;curs&amp;nbsp;=&amp;nbsp;dbconn.cursor() &lt;br /&gt;curs.execute(query) &lt;br /&gt;dbconn.commit() &lt;br /&gt;dbconn.close()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/20</guid>
      <comments>https://fathersit.tistory.com/20#entry20comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:50:08 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 주석문 안에 포함된 시스템 주요정보</title>
      <link>https://fathersit.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAK9do/btrJerAQPEG/4aQmTSVoBHmK7Kmxw0sKUK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAK9do/btrJerAQPEG/4aQmTSVoBHmK7Kmxw0sKUK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAK9do/btrJerAQPEG/4aQmTSVoBHmK7Kmxw0sKUK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAK9do%2FbtrJerAQPEG%2F4aQmTSVoBHmK7Kmxw0sKUK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 보안기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현 시 발생할 수 있는 보안약점으로 적절한 인증 없는&amp;nbsp;중요기능&amp;nbsp;허용,&amp;nbsp;부적절한&amp;nbsp;인가&amp;nbsp;등이&amp;nbsp;포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주석문 안에 포함된 시스템 주요정보&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;패스워드를 주석문에 넣어두면 시스템 보안이 훼손될 수 있다. 소프트웨어 개발자가 편의를 위해서 주석문에 패스워드를 적어둔 경우, 소프트웨어가 완성된 후에는 그것을 제거하는 것이 매우 어렵게 된다. 또한, 공격자가 소스코드에 접근할 수 있다면, 아주&amp;nbsp;쉽게&amp;nbsp;시스템에&amp;nbsp;침입할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주석에는&amp;nbsp;ID,&amp;nbsp;패스워드&amp;nbsp;등&amp;nbsp;보안과&amp;nbsp;관련된&amp;nbsp;내용을&amp;nbsp;기입하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;편리성을 위해 아이디, 패스워드 등 중요정보를 주석문 안에 작성 후 지우지 않는 경우 정보노출 보안약점이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;def&amp;nbsp;user_login(id,&amp;nbsp;passwd): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;주석문에&amp;nbsp;포함된&amp;nbsp;중요&amp;nbsp;시스템의&amp;nbsp;인증&amp;nbsp;정보 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;id&amp;nbsp;=&amp;nbsp;admin &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;passwd&amp;nbsp;=&amp;nbsp;passw0rd&lt;/span&gt; &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;login(id,&amp;nbsp;passwd) &lt;br /&gt;return&amp;nbsp;result&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 개발 시에 주석문 등에 남겨놓은 사용자 계정이나 패스워드 등의 정보는 개발 완료 시에 확실하게 삭제하여야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;def&amp;nbsp;user_login(id,&amp;nbsp;passwd): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;주석문에&amp;nbsp;포함된&amp;nbsp;민감한&amp;nbsp;정보는&amp;nbsp;삭제&lt;/span&gt; &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;login(id,&amp;nbsp;passwd) &lt;br /&gt;return&amp;nbsp;result&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/19</guid>
      <comments>https://fathersit.tistory.com/19#entry19comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:36:58 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 잘못된 세션에 의한 데이터 정보 노출</title>
      <link>https://fathersit.tistory.com/18</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UKyfv/btrJcme8Hw0/9WVkPhtItexuTTbr4FKRn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UKyfv/btrJcme8Hw0/9WVkPhtItexuTTbr4FKRn0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UKyfv/btrJcme8Hw0/9WVkPhtItexuTTbr4FKRn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUKyfv%2FbtrJcme8Hw0%2F9WVkPhtItexuTTbr4FKRn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 캡슐화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안약점으로 정보노출, 권한 문제 등이 발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;잘못된 세션에 의한 데이터 정보 노출&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다중 스레드 환경에서는 싱글톤(Singleton) 객체 필드에 경쟁조건(Race Condition)이 발생할 수 있다. 따라서, 다중 스레드 환경에서는&amp;nbsp;정보를&amp;nbsp;저장하는&amp;nbsp;전역&amp;nbsp;변수가&amp;nbsp;포함되지&amp;nbsp;않도록&amp;nbsp;하여,&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;세션에서&amp;nbsp;데이터를&amp;nbsp;공유하지&amp;nbsp;않도록&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;싱글톤 패턴을 사용하는 경우, 변수 범위(Scope)에 주의를 기울여야 한다. 특히 다중 스레드 환경에서 클래스 변수의 값은 하위&amp;nbsp;메소드와&amp;nbsp;공유되므로&amp;nbsp;필요한&amp;nbsp;경우&amp;nbsp;인스턴스&amp;nbsp;변수로&amp;nbsp;선언하여&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다중&amp;nbsp;스레드&amp;nbsp;환경에서&amp;nbsp;파이썬의&amp;nbsp;클래스&amp;nbsp;변수는&amp;nbsp;스레드&amp;nbsp;간&amp;nbsp;서로&amp;nbsp;공유하게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;클래스 변수에 값을 할당할 경우 서로 다른 세션 간에 데이터가 공유되어 의도하지 않은 데이터가 전달될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;class&amp;nbsp;UserDescription: &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;user_name&amp;nbsp;=&amp;nbsp;''&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_user_profile(self): &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;self.get_user_discription(UserDescription.user_name) &lt;br /&gt;...... &lt;br /&gt;return&amp;nbsp;result&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;show_user_profile(self,&amp;nbsp;name): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;클래스변수는&amp;nbsp;다른&amp;nbsp;세션과&amp;nbsp;공유되는&amp;nbsp;값이기&amp;nbsp;때문에&amp;nbsp;멀티스레드 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;환경에서&amp;nbsp;공유되지&amp;nbsp;말아야할&amp;nbsp;자원에&amp;nbsp;대해서&amp;nbsp;사용하는&amp;nbsp;경우 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;다른&amp;nbsp;세션에&amp;nbsp;의해&amp;nbsp;데이터가&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;UserDescription.user_name&amp;nbsp;=&amp;nbsp;name&lt;/span&gt; &lt;br /&gt;self.user_profile&amp;nbsp;=&amp;nbsp;self.get_user_profile()&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'profile.html',&amp;nbsp;{'profile':self.user_profile})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공유되어서는&amp;nbsp;안&amp;nbsp;되는&amp;nbsp;변수는&amp;nbsp;인스턴스&amp;nbsp;변수로&amp;nbsp;선언하여&amp;nbsp;세션&amp;nbsp;간&amp;nbsp;공유&amp;nbsp;되지&amp;nbsp;않도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;class&amp;nbsp;UserDescription:&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;get_user_profile(self): &lt;br /&gt;result&amp;nbsp;=&amp;nbsp;self.get_user_discription(self.user_name) &lt;br /&gt;...... &lt;br /&gt;return&amp;nbsp;result&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;show_user_profile(self,&amp;nbsp;name): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;인스턴스&amp;nbsp;변수로&amp;nbsp;사용하여&amp;nbsp;스레드&amp;nbsp;간&amp;nbsp;공유되지&amp;nbsp;못하도록&amp;nbsp;한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;self.user_name&amp;nbsp;=&amp;nbsp;name&lt;/span&gt; &lt;br /&gt;self.user_profile&amp;nbsp;=&amp;nbsp;self.get_user_profile()&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'profile.html',&amp;nbsp;{'profile':self.user_profile})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/18</guid>
      <comments>https://fathersit.tistory.com/18#entry18comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:29:56 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] DNS lookup에 의존한 보안결정</title>
      <link>https://fathersit.tistory.com/17</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4LjY8/btrJaXtvZFy/pXUawA69namEnTSQrkvuW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4LjY8/btrJaXtvZFy/pXUawA69namEnTSQrkvuW1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4LjY8/btrJaXtvZFy/pXUawA69namEnTSQrkvuW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4LjY8%2FbtrJaXtvZFy%2FpXUawA69namEnTSQrkvuW1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ API 오용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;의도된&amp;nbsp;사용에&amp;nbsp;반하는&amp;nbsp;방법으로&amp;nbsp;API를&amp;nbsp;사용하거나,&amp;nbsp;보안에&amp;nbsp;취약한&amp;nbsp;API를&amp;nbsp;사용하여&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DNS lookup에 의존한 보안결정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공격자가 DNS 엔트리를 속일 수 있으므로 도메인명에 의존에서 보안결정(인증 및 접근 통제 등)을 하지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;만약, 로컬 DNS 서버의 캐시가 공격자에 의해 오염된 상황이라면, 사용자와 특정 서버 간의 네트워크 트래픽이 공격자를 경유하도록 할&amp;nbsp;수도&amp;nbsp;있다.&amp;nbsp;또한,&amp;nbsp;공격자가&amp;nbsp;마치&amp;nbsp;동일&amp;nbsp;도메인에&amp;nbsp;속한&amp;nbsp;서버인&amp;nbsp;것처럼&amp;nbsp;위장할&amp;nbsp;수도&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안결정에서&amp;nbsp;도메인명을&amp;nbsp;이용한&amp;nbsp;DNS&amp;nbsp;lookup을&amp;nbsp;하지&amp;nbsp;않도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음의 예제는 도메인명을 통해 해당 요청을 신뢰할 수 있는지를 검사한다. 그러나 공격자는 DNS 캐쉬 등을 조작해서 쉽게 이러한&amp;nbsp;보안&amp;nbsp;설정을&amp;nbsp;우회할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;socket&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;is_trust(host_domain_name): &lt;br /&gt;trusted&amp;nbsp;=&amp;nbsp;False &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;trusted_host&amp;nbsp;=&amp;nbsp;&quot;trust.example.com&quot; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;공격자에&amp;nbsp;의해&amp;nbsp;실행되는&amp;nbsp;서버의&amp;nbsp;DNS가&amp;nbsp;변경될&amp;nbsp;수&amp;nbsp;있으므로 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않다 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;if&amp;nbsp;trusted_host&amp;nbsp;==&amp;nbsp;host_name:&lt;/span&gt; &lt;br /&gt;trusted&amp;nbsp;=&amp;nbsp;True &lt;br /&gt;return&amp;nbsp;trusted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;도메인명을&amp;nbsp;이용한&amp;nbsp;비교를&amp;nbsp;하지&amp;nbsp;말고&amp;nbsp;IP&amp;nbsp;주소를&amp;nbsp;직접&amp;nbsp;비교하도록&amp;nbsp;수정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;socket&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;is_trust(host_domain_name): &lt;br /&gt;trusted&amp;nbsp;=&amp;nbsp;False &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;trusted_ip&amp;nbsp;=&amp;nbsp;&quot;192.168.10.7&amp;ldquo; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;실제&amp;nbsp;서버의&amp;nbsp;IP&amp;nbsp;주소를&amp;nbsp;비교하여&amp;nbsp;DNS&amp;nbsp;변조에&amp;nbsp;대응 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;dns_resolved_ip&amp;nbsp;=&amp;nbsp;socket.gethostbyaddr(host_domain_name)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;trusted_ip&amp;nbsp;==&amp;nbsp;dns_resolved_ip:&lt;/span&gt; &lt;br /&gt;trusted&amp;nbsp;=&amp;nbsp;True &lt;br /&gt;return&amp;nbsp;trusted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/17</guid>
      <comments>https://fathersit.tistory.com/17#entry17comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:25:29 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 신뢰할 수 없는 데이터의 역직렬화</title>
      <link>https://fathersit.tistory.com/16</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2RRPb/btrI3y8BeEF/mYqDLkb4qKELJduBhcahb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2RRPb/btrI3y8BeEF/mYqDLkb4qKELJduBhcahb1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2RRPb/btrI3y8BeEF/mYqDLkb4qKELJduBhcahb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2RRPb%2FbtrI3y8BeEF%2FmYqDLkb4qKELJduBhcahb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 코드오류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;타입 변환 오류, 자원(메모리 등)의 부적절한 반환 등과 같이 개발자가 범할 수 있는 코딩 오류로 인해 유발되는 보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;신뢰할 수 없는 데이터의 역직렬화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;직렬화(Serialization)는 프로그램에서 특정 클래스의 현재 인스턴스 상태를 다른 서버로 전달하기 위해 클래스의 인스턴스 정보를 바이트 스트림으로 복사하는 작업으로, 메모리상에서 실행되고 있는 객체의 상태를 그대로 복제하여 파일로 저장하거나 수신&amp;nbsp;측에&amp;nbsp;전달하게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;역직렬화(Deserialization)는 반대 연산으로 바이너리 파일(Binary File) 이나 바이트 스트림(Byte Stream)으로부터 객체 구조로 복원하게 된다. 이 때, 송신자가 네트워크를 이용하여 직렬화된 정보를 수신자에게 전달하는 과정에서 공격자가 전송 또는 저장된 스트림을 조작할 수 있는 경우에는 신뢰할 수 없는 역직렬화를 이용하여 무결성 침해, 원격 코드 실행, 서비스 거부&amp;nbsp;공격&amp;nbsp;등이&amp;nbsp;발생&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서는 pickle 모듈을 통해 직렬화 및 역직렬화를 지원하고 각각 pickle, unpickle로 명칭한다. pickle 모듈은 데이터 변조에 대한 검증 과정이 없기 때문에 임의의 코드를 실행하는 악의적인 pickle 데이터를 구성할 수 있어 pickle을 사용하여 역직렬화&amp;nbsp;하는&amp;nbsp;경우&amp;nbsp;hmac으로&amp;nbsp;데이터에&amp;nbsp;서명하거나,&amp;nbsp;json&amp;nbsp;모듈을&amp;nbsp;사용하는&amp;nbsp;것을&amp;nbsp;고려해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;초기화되지 않은 스택 메모리 영역의 변수는 임의 값이라 생각해서 대수롭지 않게 생각할 수 있으나 사실은 이전 함수에서 사용되었던 내용을 포함하고 있다. 공격자는 이러한 약점을 사용하여 메모리에 저장되어 있는 값을 읽거나 특정 코드를 실행할 수&amp;nbsp;있다.&amp;nbsp;모든&amp;nbsp;변수를&amp;nbsp;사용&amp;nbsp;전에&amp;nbsp;반드시&amp;nbsp;올바른&amp;nbsp;초기&amp;nbsp;값을&amp;nbsp;할당함으로서&amp;nbsp;이러한&amp;nbsp;문제를&amp;nbsp;예방한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;신뢰할 수 없는 데이터를 역직렬화 하지 않도록 응용프로그램을 구성한다. 민감정보 또는 중요정보를 전송 시 암호화 통신을 적용하지&amp;nbsp;못하는&amp;nbsp;경우,&amp;nbsp;송신&amp;nbsp;측에서&amp;nbsp;서명을&amp;nbsp;추가하고&amp;nbsp;수신&amp;nbsp;측에서&amp;nbsp;서명을&amp;nbsp;확인하여&amp;nbsp;데이터의&amp;nbsp;무결성을&amp;nbsp;검증한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또는, 신뢰할수 있는 데이터의 식별을 위해 역직렬화 대상의 데이터가 사전에 검증된 클래스(Class)만을 포함하는지 검증하거나, 제한된 실행&amp;nbsp;권한을&amp;nbsp;구성하여&amp;nbsp;역직렬화&amp;nbsp;코드를&amp;nbsp;실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 알 수 없는 사용자로부터 입력 받은 코드를 역직렬화 하고 있는데, 이와 같은 코드는 개발자가 의도하지 않은 임의&amp;nbsp;코드가&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;pickle &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;load_user_object(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;userinfo&amp;nbsp;=&amp;nbsp;bytes(request.POST.get('userinfo',&amp;nbsp;''),&amp;nbsp;encoding&amp;nbsp;=&amp;nbsp;&quot;utf-8&quot;) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자로부터&amp;nbsp;입력받은&amp;nbsp;알&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;데이터를&amp;nbsp;직렬화 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;user_obj&amp;nbsp;=&amp;nbsp;pickle.loads(userinfo)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/load_user_obj.html',&amp;nbsp;{'obj':user_obj})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 예제는 사용자로부터 전달받은 데이터를 hmac을 이용하여 안전한 사용자로부터 온 것인지 검증한 후 역직렬화 하고 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;hmac &lt;br /&gt;import&amp;nbsp;hashlib &lt;br /&gt;import&amp;nbsp;pickle &lt;br /&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;load_user_object(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;hash_pickle&amp;nbsp;=&amp;nbsp;bytes(request.POST.get('hash_pickle',&amp;nbsp;''),&amp;nbsp;encoding&amp;nbsp;=&amp;nbsp;&quot;utf-8&quot;)&lt;/span&gt; &lt;br /&gt;userinfo&amp;nbsp;=&amp;nbsp;bytes(request.POST.get('userinfo',&amp;nbsp;''),&amp;nbsp;encoding&amp;nbsp;=&amp;nbsp;&quot;utf-8&quot;) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;HMAC&amp;nbsp;검증을&amp;nbsp;위한&amp;nbsp;비밀키는&amp;nbsp;안전하게&amp;nbsp;저장하여&amp;nbsp;사용&lt;/span&gt; &lt;br /&gt;m&amp;nbsp;=&amp;nbsp;hmac.new(key=b&amp;rsquo;secret_key&amp;rsquo;,&amp;nbsp;digestmod=hashlib.sha512) &lt;br /&gt;m.update(userinfo) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;전달받은&amp;nbsp;해시값(hash_pickle)과&amp;nbsp;직렬화&amp;nbsp;데이터(userinfo)의 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;해시값을&amp;nbsp;비교하여&amp;nbsp;검증 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;hmac.compare_digest(m.digest(),&amp;nbsp;hash_pickle):&lt;/span&gt; &lt;br /&gt;user_obj&amp;nbsp;=&amp;nbsp;pickle.loads(userinfo_pickle) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/load_user_obj.html',&amp;nbsp;{'obj':user_obj}) &lt;br /&gt;else: &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error.html',&amp;nbsp;{'error':'직렬화&amp;nbsp;오류입니다.'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 외에도 내부의 데이터만을 필요로 하는 경우에는 JSON과 같은 텍스트 형태의 안전한 직렬화 형식을 사용하는 것이 옳다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/16</guid>
      <comments>https://fathersit.tistory.com/16#entry16comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:17:49 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 크로스 사이트 스크립트(XSS)</title>
      <link>https://fathersit.tistory.com/15</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHSP1D/btrI9mUDcZZ/agYUegso3hWiT23oCBOynk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHSP1D/btrI9mUDcZZ/agYUegso3hWiT23oCBOynk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHSP1D/btrI9mUDcZZ/agYUegso3hWiT23oCBOynk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHSP1D%2FbtrI9mUDcZZ%2FagYUegso3hWiT23oCBOynk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;크로스 사이트 스크립트 (XSS)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;크로스사이트 스크립트 공격(Cross-site scripting Attacks)은 웹사이트에 악성 코드를 삽입하는 공격 방법이다. 공격자는 대상 웹 응용 프로그램의 결함을 이용하여 악성코드(일반적으로 클라이언트 측 JavaScript 사용)를 사용자에게 보낸다. XSS 공격은&amp;nbsp;일반적으로&amp;nbsp;애플리케이션의&amp;nbsp;호스트&amp;nbsp;자체를&amp;nbsp;대상으로&amp;nbsp;하지&amp;nbsp;않고&amp;nbsp;애플리케이션의&amp;nbsp;사용자를&amp;nbsp;목표로&amp;nbsp;삼는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;XSS는 공격자가 웹 응용프로그램을 속여 사용자의 브라우저에서 실행할 수 있는 형식의 데이터를 보 때 발생한다. 일반적인 HTML과 공격자가 제공한 XSS코드의 조합 뿐만 아니라 악성코드 다운로드, 플러그인 또는 미디어 콘텐츠를 이용하기도 한다. 사용자가 양식에 입력한 데이터 또는 서버에서 클라이언트 소프트웨어(브라우저 또는 WebKit등)의 종료점(endpoint)으로&amp;nbsp;전달된&amp;nbsp;데이터가&amp;nbsp;적절한&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용자에게&amp;nbsp;표시되도록&amp;nbsp;허용하는&amp;nbsp;경우&amp;nbsp;발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;XSS공격은&amp;nbsp;크게&amp;nbsp;세가지&amp;nbsp;유형의&amp;nbsp;공격방법이&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;⦁유형&amp;nbsp;1&amp;nbsp;:&amp;nbsp;Reflective&amp;nbsp;XSS&amp;nbsp;(or&amp;nbsp;Non-persistent&amp;nbsp;XSS) &lt;br /&gt;- Reflective XSS는 공격 코드를 사용자의 HTTP 요청에 삽입시킨 뒤, 해당 공격 코드가 서버 응답 내용에 그대로 반사 (Reflected)되어 브라우저에서 실행시키는 공격기법이다. Reflective XSS를 악용하려면 공격자가 사용자 속여 대상 사이트로 데이터를 보내도록 해야 한다. 이 방법은 종종 사용자가 악의적으로 제작된 링크를 클릭하도록 속임으로써 수행 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대부분의 경우 Reflective XSS공격 메커니즘은 공개적으로 게시되거나 피해자 전송되는 피싱(Phishing) 이메일 또는 단축 URL 또는 모호한 URL에 매개 변수로 포함하는 방법이다. 이러한 방식으로 구성된 URL은 많은 피싱 체계의 핵심을 구성하며, 공격자는 피해자가 취약한 사이트를 참조하는 URL을 방문하도록 유도한다. 피해자가 링크를 방문하면 스크립트가&amp;nbsp;피해자의&amp;nbsp;브라우저에서&amp;nbsp;자동으로&amp;nbsp;실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;⦁유형&amp;nbsp;2&amp;nbsp;:&amp;nbsp;Persistent&amp;nbsp;XSS&amp;nbsp;(or&amp;nbsp;Stored&amp;nbsp;XSS) &lt;br /&gt;- Persistent XSS는 신뢰할 수 없거나 확인되지 않은 사용자 입력이 대상 서버에 저장될 때 발생한다. Persistent XSS의 일반적인 대상에는 게시판 글, 댓글 또는 방문자 로그가 포함된다. 이 기능들은 인증되거나 인증되지 않은 다른 사용자가 공격자의 악성 콘텐츠를 볼 수 있는 기능이다. 소셜(Social) 미디어 사이트 및 회원 그룹에서 흔히 볼 수 있는 것과 같이 공개적으로 표시되는 프로필 페이지는 Persistent XSS의 손쉬운 공격 대상 중 하나입니다. 공격자는 프로필 입력박스에 악성&amp;nbsp;스크립트를&amp;nbsp;입력할&amp;nbsp;수&amp;nbsp;있으며&amp;nbsp;다른&amp;nbsp;사용자가&amp;nbsp;프로필을&amp;nbsp;방문하면&amp;nbsp;브라우저에서&amp;nbsp;자동으로&amp;nbsp;코드가&amp;nbsp;실행되도록&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;⦁유형&amp;nbsp;3&amp;nbsp;:&amp;nbsp;DOM&amp;nbsp;기반&amp;nbsp;XSS&amp;nbsp;(or&amp;nbsp;Client-Side&amp;nbsp;XSS) &lt;br /&gt;- DOM 기반 XSS은 공격 스크립트가 포함된 악성 URL을 통해 전달되는 경우가 많기 때문에 Reflective XSS와 어느정도 유사하다. 그러나 신뢰할 수 있는 사이트의 HTTP 응답에 페이로드를 포함하는 대신 DOM 또는 문서 개체 모델을 수정하여 브라우저에서 독립적으로 완전한 공격을 실행한다. 이는 웹 페이지에 있는 사용자 입력 값을 적절하게 처리하기 위한&amp;nbsp;JavaScript의&amp;nbsp;검증&amp;nbsp;로직을&amp;nbsp;무효화&amp;nbsp;하는&amp;nbsp;것을&amp;nbsp;목표로&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;악성 스크립트가 삽입되면 공격자는 다양한 악성 활동을 수행 할 수 있다. 공격자는 세션 정보를 포함 한 쿠키와 같은 개인 정보를 피해자의 컴퓨터에서 공격자에게 전송할 수 있다. 공격자는 피해자의 정로를 사용하여 웹 사이트에 악의적인 요청을 보낼 수 있으며, 피해자가 해당 사이트를 관리 할 수 있는 관리자 권한이 있는 경우 사이트에 특히 위험할 수 있다. 피싱(Phishing) 공격은 신뢰할 수 있는 웹 사이트를 모방하고 피해자가 암호를 입력하도록 속여 공격자가 해당&amp;nbsp;웹&amp;nbsp;사이트에서&amp;nbsp;피해자의&amp;nbsp;계정을&amp;nbsp;손상시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;파이썬에서 가장 많이 사용하고 있는 Django 프레임워크와 Flask 프레임워크에서는 각각 Django 템플릿과 Jinja2 템플릿을 사용할 시 크로스사이트 스크립트 공격에 사용될 수 있는 위험한 HTML 문자에 대해 HTML 특수문자 (HTML Entities)로 치환하는 기능을 제공하고 있어 프레임워크에서 제공하는 템플릿을 사용하는 경우 안전하게 사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부 입력값 또는 출력값에 스크립트가 삽입되지 못하도록 문자열 치환 함수를 사용하여 &amp;amp;&amp;lt;&amp;gt;*&amp;lsquo;/()등을 &amp;amp;amp; &amp;amp;lt; &amp;amp;gt; &amp;amp;quot; &amp;amp;#x27; &amp;amp;#x2F; &amp;amp;#x28; &amp;amp;#x29;로 치환하거나, html라이브러리의 escape()를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;HTML 태그를 허용하는게시판에서는 허용되는 HTML 태그들을 화이트리스트로 만들어 해당 태그만 지원하도록 한다. 파이썬에서 가장 많이 사용하는 프레임워크인 Django, Flask등을 사용하는 경우 외부 입력값에 악의적인 스크립트가 삽입되지 못하도록 프레임워크 자체에서 크로스사이트 스크립트 공격에 사용될 수 있는 문자를 HTML 특수문자(HTML Entities)로 치환하여 응답 페이지를 생성하므로 크로스사이트 스크립트로부터 보호된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프레임워크에서 크로스사이트 스크립트 공격으로부터 보호해 주는 기능이 있더라도 완전하지 않은 경우도 있고 개발자의 실수로 보호기능이 무효화 되는 경우가 있어 주의를기울여야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Django&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django 프레임워크는 크로스사이트 스크립트 공격에 대한 보안기능을 내장하고 있지만 유의해야 할 사항이 몇 가지 있다. Django의 &amp;ldquo;safestring(django.utils.safestring)&amp;rdquo;의 기능을 오용할 경우 Django의 크로스사이트 스크립트 보호 정책이 무력화&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;django.utils.safestring&amp;nbsp;import&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;mark_safe&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;profile_link(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;HTML&amp;nbsp;태그&amp;nbsp;생성의&amp;nbsp;인자로&amp;nbsp;사용&lt;/span&gt; &lt;br /&gt;profile_url&amp;nbsp;=&amp;nbsp;request.POST.get('profile_url') &lt;br /&gt;profile_name&amp;nbsp;=&amp;nbsp;requst.POST.get('profile_name')&lt;br /&gt;&lt;br /&gt;object_link&amp;nbsp;=&amp;nbsp;'&amp;lt;a&amp;nbsp;href=&quot;{}&quot;&amp;gt;{}&amp;lt;/a&amp;gt;'.format(profile_url,&amp;nbsp;profile_name) &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;mark_safe함수는&amp;nbsp;Django의&amp;nbsp;XSS&amp;nbsp;escape&amp;nbsp;정책을&amp;nbsp;따르지&amp;nbsp;않는다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;object_link&amp;nbsp;=&amp;nbsp;mark_safe(object_link)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'my_profile.html',{'object_link':object_link})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django 프레임워크는 템플릿 생성 시 HTML에서 위험한 것으로 간주되는 특수 문자(&amp;ldquo;&amp;lt;&amp;rdquo;, &amp;ldquo;&amp;gt;&amp;rdquo;, &amp;ldquo;&amp;lsquo;&amp;rdquo;, &amp;ldquo;&amp;rdquo;&amp;rdquo;, &amp;ldquo;&amp;amp;&amp;rdquo;)를 모두 html 엔티티로&amp;nbsp;치환&amp;nbsp;하지만&amp;nbsp;mark_safe를&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;이&amp;nbsp;정책을&amp;nbsp;따르지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;따라서 mark_safe 함수를 사용 할 경우에는 각별한 주의가 필요하고 신뢰할 수 없는 데이터에 대해서는 mark_safe 함수를 사용하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;profile_link(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;HTML&amp;nbsp;태그&amp;nbsp;생성의&amp;nbsp;인자로&amp;nbsp;사용&lt;/span&gt; &lt;br /&gt;profile_url&amp;nbsp;=&amp;nbsp;request.POST.get('profile_url') &lt;br /&gt;profile_name&amp;nbsp;=&amp;nbsp;requst.POST.get('profile_name')&lt;br /&gt;&lt;br /&gt;object_link&amp;nbsp;=&amp;nbsp;'&amp;lt;a&amp;nbsp;href=&quot;{}&quot;&amp;gt;{}&amp;lt;/a&amp;gt;'.format(profile_url,&amp;nbsp;profile_name) &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;신뢰&amp;nbsp;할&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;데이터에&amp;nbsp;대해서는&amp;nbsp;mark_safe&amp;nbsp;함수를&amp;nbsp;사용하지&amp;nbsp;않는다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'my_profile.html',{'object_link':object_link})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 Django 프레임워크에서의 템플릿 예제이다. autoescape 블록을 사용 시 설정값을 off로 할 경우와 개별 변수에 대해서&amp;nbsp;safe&amp;nbsp;필터를&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;크로스사이트&amp;nbsp;스크립트&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;&amp;lt;!doctype&amp;nbsp;html&amp;gt; &lt;br /&gt;&amp;lt;html&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt; &lt;br /&gt;&amp;lt;div&amp;nbsp;class=&quot;content&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;{%&amp;nbsp;autoescape&amp;nbsp;off&amp;nbsp;%} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;//&amp;nbsp;autoescape&amp;nbsp;off로&amp;nbsp;해당&amp;nbsp;블록내의&amp;nbsp;데이터는&amp;nbsp;XSS&amp;nbsp;공격에 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;//&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있음. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;{{&amp;nbsp;content&amp;nbsp;}} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;{%&amp;nbsp;endautoescape&amp;nbsp;%}&lt;/span&gt; &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;div&amp;nbsp;class=&quot;content2&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;//safe&amp;nbsp;필터&amp;nbsp;사용으로&amp;nbsp;XSS&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있음. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;{{&amp;nbsp;content&amp;nbsp;|&amp;nbsp;safe&amp;nbsp;}}&lt;/span&gt; &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/body&amp;gt; &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;신뢰할 수 없는 입력값 또는 동적 데이터에 대해서는 autoescape 옵션 값을 on으로 하고 safe 필터를 부득이 하게 사용할 경우&amp;nbsp;추가적인&amp;nbsp;보안대책이&amp;nbsp;필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&amp;lt;!doctype&amp;nbsp;html&amp;gt; &lt;br /&gt;&amp;lt;html&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt; &lt;br /&gt;&amp;lt;div&amp;nbsp;class=&quot;content&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;{%&amp;nbsp;autoescape&amp;nbsp;on&amp;nbsp;%}&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;//&amp;nbsp;autoescape&amp;nbsp;on로&amp;nbsp;해당&amp;nbsp;블록내의&amp;nbsp;데이터는&amp;nbsp;XSS&amp;nbsp;공격에 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;{{&amp;nbsp;content&amp;nbsp;}} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;{%&amp;nbsp;endautoescape&amp;nbsp;%}&lt;/span&gt; &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;div&amp;nbsp;class=&quot;content2&quot;&amp;gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;//검증되지&amp;nbsp;않은&amp;nbsp;데이터에는&amp;nbsp;safe&amp;nbsp;필터를&amp;nbsp;사용하지&amp;nbsp;않는다.&lt;/span&gt; &lt;br /&gt;{{&amp;nbsp;content&amp;nbsp;}} &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/body&amp;gt; &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;autoescape 블록을 사용할 경우 많은 주의를 기울여야 한다. autoescape 옵션값을 off로 설정한 템플릿 페이지를 include 또는 extends하는 템플릿까지 영향이 확장된다. 공통적으로 사용하는 템플릿페이지에 off로 설정할 경우 많은 템플릿 페이지가&amp;nbsp;크로스사이트&amp;nbsp;스크립트&amp;nbsp;공격에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ Flask에서의&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자의 요청에 포함된 값 또는 DB에 저장된 값 또는 내부의 연산을 통해서 생성된 값을 포함 한 값은 동적 웹 페이지 생성에 사용하는 경우 크로스사이트 스크립트(XSS) 공격이 발생할 가능성이 있어 위험하다. 아래 예제는 Flask 프레임워크를 사용한&amp;nbsp;안전하지&amp;nbsp;않은&amp;nbsp;예제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask,&amp;nbsp;request,&amp;nbsp;render_template&lt;br /&gt;&lt;br /&gt;@app.route('/search',&amp;nbsp;methods=['POST']) &lt;br /&gt;def&amp;nbsp;search(): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;search_keyword&amp;nbsp;=&amp;nbsp;request.form.get('search_keyword') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;입력을&amp;nbsp;아무런&amp;nbsp;검증&amp;nbsp;또는&amp;nbsp;치환&amp;nbsp;없이&amp;nbsp;동적&amp;nbsp;웹&amp;nbsp;페이지에&amp;nbsp;사용하고&amp;nbsp;있어 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;크로스&amp;nbsp;사이트&amp;nbsp;스크립트가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render_template('search.html',&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;search_keyword=search_keyword)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동적 웹 페이지 생성에 사용되는 데이터를 HTML 엔티티 코드 (Entity Code)로 치환하여 안전하게 표현하여야 한다. html.escape 메소드는 문자열의 &amp;amp;, &amp;lt; 및 &amp;gt; 특수문자를 HTML에서 안전한 값으로 변환한다. 옵션 값의 quote 값이 True이면 문자 (&amp;ldquo;)와 (&amp;lsquo;)도 변환된다. &amp;lt;a href=&amp;rdquo;&amp;hellip;&amp;ldquo;&amp;gt;에서처럼 따옴표로 구분된 HTML 어트리뷰트 값에 포함하는 문자열을 포함할 경우 사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;html &lt;br /&gt;from&amp;nbsp;flask&amp;nbsp;import&amp;nbsp;Flask,&amp;nbsp;request,&amp;nbsp;render_template&lt;br /&gt;&lt;br /&gt;@app.route('/search',&amp;nbsp;methods=['POST']) &lt;br /&gt;def&amp;nbsp;search(): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;search_keyword&amp;nbsp;=&amp;nbsp;request.form.get('search_keyword')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;동적&amp;nbsp;웹&amp;nbsp;페이지&amp;nbsp;생성에&amp;nbsp;사용되는&amp;nbsp;데이터는 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;HTML&amp;nbsp;엔티티코드로&amp;nbsp;치환하여&amp;nbsp;표현해야한다&lt;/span&gt; &lt;br /&gt;escape_keyword&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;html.escape(search_keyword)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render_template('search.html',&amp;nbsp;search_keyword=escape_keyword)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/15</guid>
      <comments>https://fathersit.tistory.com/15#entry15comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:15:03 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 오류 메시지 정보노출</title>
      <link>https://fathersit.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTmHYK/btrJeqhF6zQ/K3RmkvTIFBgL5Mz2RyI9R0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTmHYK/btrJeqhF6zQ/K3RmkvTIFBgL5Mz2RyI9R0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTmHYK/btrJeqhF6zQ/K3RmkvTIFBgL5Mz2RyI9R0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTmHYK%2FbtrJeqhF6zQ%2FK3RmkvTIFBgL5Mz2RyI9R0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 에러처리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;에러를 처리하지 않거나, 불충분하게 처리하여 에러 정보에 중요정보(시스템 내부정보 등)가 포함될 때, 발생할 수 있는 취약점으로&amp;nbsp;에러를&amp;nbsp;부적절하게&amp;nbsp;처리하여&amp;nbsp;발생하는&amp;nbsp;보안약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;오류 메시지 정보노출&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응용프로그램이 실행환경, 사용자 등 관련 데이터에 대한 민감한 정보를 포함하는 오류 메시지를 생성하여 외부에 제공하는 경우, 공격자의 악성 행위를 도울 수 있다. 예외발생 시 예외 이름이나 트레이스백(traceback)를 출력하는 경우, 프로그램 내부 구조를&amp;nbsp;쉽게&amp;nbsp;파악할&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Django 프레임워크와 Flask 프레임워크는 HTTP 오류 코드가 있는 요청을 처리하기 위한 사용자 에러 페이지 핸들러를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오류 메시지는 정해진 사용자에게 유용한 최소한의 정보만 포함하도록 한다. 소스코드에서 예외 상황은 내부적으로 처리하고 사용자에게&amp;nbsp;시스템&amp;nbsp;내부&amp;nbsp;정보&amp;nbsp;등&amp;nbsp;민감한&amp;nbsp;정보를&amp;nbsp;포함하는&amp;nbsp;오류를&amp;nbsp;출력하지&amp;nbsp;않도록&amp;nbsp;미리&amp;nbsp;정의된&amp;nbsp;메시지를&amp;nbsp;제공하도록&amp;nbsp;설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Django&amp;nbsp;프레임워크에서는&amp;nbsp;urls.py에&amp;nbsp;사용자&amp;nbsp;정의&amp;nbsp;에러&amp;nbsp;페이지를&amp;nbsp;핸들러를&amp;nbsp;정의&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자 요청을 처리할 수 없는 경우 에러 페이지에 디버그 정보 또는 서버의 정보가 노출될 수 있다. 만일 어플리케이션을 배포 할 때 DEBUG 모드를 True로 설정 하고 배포할 경우에 아래와 같이 시스템의 주요 정보가 노출 될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django는 DEBUG 모드를 False로 배포했을 경우 아래와 같이 사용자 에러페이지를 설정하지 않을 경우에는 Django 기본 에러페이지가&amp;nbsp;보이게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;#&amp;nbsp;config/urls.py &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;별도&amp;nbsp;에러페이지를&amp;nbsp;선언하지&amp;nbsp;않아&amp;nbsp;django의&amp;nbsp;기본&amp;nbsp;에러페이지를&amp;nbsp;출력한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제공되는&amp;nbsp;에러&amp;nbsp;페이지&amp;nbsp;핸들러를&amp;nbsp;이용해&amp;nbsp;별도의&amp;nbsp;에러&amp;nbsp;페이지를&amp;nbsp;생성하여&amp;nbsp;사용자에게&amp;nbsp;표현하고&amp;nbsp;서버의&amp;nbsp;정보노출을&amp;nbsp;최소화&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;#&amp;nbsp;config/urls.py &lt;br /&gt;from&amp;nbsp;django.conf.urls&amp;nbsp;import&amp;nbsp;handler400,&amp;nbsp;handler403,&amp;nbsp;handler404,&amp;nbsp;handler500&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자&amp;nbsp;정의&amp;nbsp;에러페이지를&amp;nbsp;지정하고 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;views.py에&amp;nbsp;사용자&amp;nbsp;정의&amp;nbsp;에러페이지에&amp;nbsp;대한&amp;nbsp;코드를&amp;nbsp;구현하여&amp;nbsp;사용한다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;handler400&amp;nbsp;=&amp;nbsp;&quot;blog.views.error400&quot; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;handler403&amp;nbsp;=&amp;nbsp;&quot;blog.views.error403&quot; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;handler404&amp;nbsp;=&amp;nbsp;&quot;blog.views.error404&quot; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;handler500&amp;nbsp;=&amp;nbsp;&quot;blog.views.error500&amp;ldquo;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래는&amp;nbsp;traceback을&amp;nbsp;사용하여&amp;nbsp;에러&amp;nbsp;스택을&amp;nbsp;표준출력으로&amp;nbsp;표시하는&amp;nbsp;예제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;traceback&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;fetch_url(url,&amp;nbsp;useragent,&amp;nbsp;referer=None,&amp;nbsp;retries=1,&amp;nbsp;dimension=False): &lt;br /&gt;...... &lt;br /&gt;try: &lt;br /&gt;response&amp;nbsp;=&amp;nbsp;requests.get(url,&amp;nbsp;stream=True,&amp;nbsp;timeout=5,&amp;nbsp;headers={ &lt;br /&gt;'User-Agent':&amp;nbsp;useragent, &lt;br /&gt;'Referer':&amp;nbsp;referer, &lt;br /&gt;}) &lt;br /&gt;...... &lt;br /&gt;except&amp;nbsp;IOError: &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;에러메시지를&amp;nbsp;통해&amp;nbsp;스택정보가&amp;nbsp;노출됨. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;traceback.print_exc()&lt;/span&gt; &lt;br /&gt;break&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오류&amp;nbsp;처리&amp;nbsp;시&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;에러&amp;nbsp;이름이나&amp;nbsp;에러&amp;nbsp;추적&amp;nbsp;정보가&amp;nbsp;노출&amp;nbsp;되지&amp;nbsp;않도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;import&amp;nbsp;logging&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;fetch_url(url,&amp;nbsp;useragent,&amp;nbsp;referer=None,&amp;nbsp;retries=1,&amp;nbsp;dimension=False): &lt;br /&gt;...... &lt;br /&gt;try: &lt;br /&gt;response&amp;nbsp;=&amp;nbsp;requests.get(url,&amp;nbsp;stream=True,&amp;nbsp;timeout=5,&amp;nbsp;headers={ &lt;br /&gt;'User-Agent':&amp;nbsp;useragent, &lt;br /&gt;'Referer':&amp;nbsp;referer, &lt;br /&gt;}) &lt;br /&gt;...... &lt;br /&gt;except&amp;nbsp;IOError: &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;에러&amp;nbsp;코드와&amp;nbsp;정보를&amp;nbsp;별도로&amp;nbsp;정의하고&amp;nbsp;최소&amp;nbsp;정보만&amp;nbsp;로깅 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;logger.info('ERROR-01:통신에러')&lt;/span&gt; &lt;br /&gt;break&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/14</guid>
      <comments>https://fathersit.tistory.com/14#entry14comment</comments>
      <pubDate>Tue, 9 Aug 2022 00:10:38 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] Public 메소드로부터 반환된 Private 배열</title>
      <link>https://fathersit.tistory.com/13</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czUaAt/btrJgxmxwBr/CiOHL1y6aYgOR3YmWmt8u0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czUaAt/btrJgxmxwBr/CiOHL1y6aYgOR3YmWmt8u0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czUaAt/btrJgxmxwBr/CiOHL1y6aYgOR3YmWmt8u0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczUaAt%2FbtrJgxmxwBr%2FCiOHL1y6aYgOR3YmWmt8u0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 캡슐화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안약점으로 정보노출, 권한 문제 등이 발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Public 메소드로부터 반환된 Private 배열&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python은 명시적인 private 선언이 없다. 하지만 대부분의 Python 코드가 따르는 규칙으로 이름 앞에 밑줄(예:__spam)로 시작하면 Private으로 처리된다. 배열을 public으로 선언된 메소드를 통해 반환(return)하면, 그 배열의 레퍼런스가 외부에 공개되어&amp;nbsp;외부에서&amp;nbsp;배열&amp;nbsp;수정과&amp;nbsp;객체&amp;nbsp;속성변경이&amp;nbsp;가능해진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;배열 뿐 아니라 변경 가능한(mutable) 객체에 대해 모두 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;public - attribute, method는 기본적으로 public&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;protect - attribute, method 앞에 _(single underscore)를 붙여서 표시 함. 실제&amp;nbsp;제약&amp;nbsp;보다는&amp;nbsp;관례적임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;private - attribute, method 앞에 __(double underscore)를 붙여서 표시 함. 파이썬은 네임 맹글링(name mangling)으로 private 멤버에 _class__member로 접근은 가능하지만 바람직하지&amp;nbsp;않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;private로 선언된 배열을 public으로 선언된 메소드를 통해 반환하지 않도록 해야 한다. private 배열에 대한 복사본을 반환하도록 하고 배열의 원소에 대해서는 clone() 메소드를 통해 복사된 원소를 저장하도록 하여 private 선언된 배열과 객체 속성에&amp;nbsp;대한&amp;nbsp;의도하지&amp;nbsp;않게&amp;nbsp;수정되는&amp;nbsp;것을&amp;nbsp;방지한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;만약 배열의 원소가 String 타입 등과 같이 변경이 되지 않는 경우에는 Private&amp;nbsp;배열의&amp;nbsp;복사본을&amp;nbsp;만들고&amp;nbsp;이를&amp;nbsp;반환하도록&amp;nbsp;작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 예제는 __를 이용해서 Python의 private 배열을 생성하고 그것을 반환하는 public 메소드를 사용하고 있다. 이 경우 특정&amp;nbsp;배열&amp;nbsp;타입에&amp;nbsp;따라&amp;nbsp;외부에서&amp;nbsp;private&amp;nbsp;배열을&amp;nbsp;변조할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문제를&amp;nbsp;내포하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;import&amp;nbsp;copy &lt;br /&gt;class&amp;nbsp;UserObj(): &lt;br /&gt;__private_variable&amp;nbsp;=&amp;nbsp;[] &lt;br /&gt;def&amp;nbsp;__init__(self): &lt;br /&gt;pass&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;private&amp;nbsp;배열을&amp;nbsp;리턴하는&amp;nbsp;public&amp;nbsp;메소드를&amp;nbsp;사용하는&amp;nbsp;경우&amp;nbsp;취약함&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;get_private_member(self): &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;return&amp;nbsp;self.__private_variable&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래&amp;nbsp;예제는&amp;nbsp;내부와&amp;nbsp;외부의&amp;nbsp;배열이&amp;nbsp;서로&amp;nbsp;참조되는&amp;nbsp;것을&amp;nbsp;예방하기&amp;nbsp;위해&amp;nbsp;[:]로&amp;nbsp;새로운&amp;nbsp;객체를&amp;nbsp;생성하여&amp;nbsp;값을&amp;nbsp;반환하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;class&amp;nbsp;UserObj(): &lt;br /&gt;__private_variable&amp;nbsp;=&amp;nbsp;[] &lt;br /&gt;def&amp;nbsp;__init__(self): &lt;br /&gt;pass&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;private&amp;nbsp;배열을&amp;nbsp;반환하는&amp;nbsp;경우&amp;nbsp;[:]를&amp;nbsp;사용하여&amp;nbsp;외부와&amp;nbsp;내부의 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;배열이&amp;nbsp;서로&amp;nbsp;참조되지&amp;nbsp;않도록&amp;nbsp;해야&amp;nbsp;한다&lt;/span&gt; &lt;br /&gt;def&amp;nbsp;get_private_member(self): &lt;br /&gt;return&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;self.__private_variable[:]&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/13</guid>
      <comments>https://fathersit.tistory.com/13#entry13comment</comments>
      <pubDate>Mon, 8 Aug 2022 23:24:52 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] 코드 삽입</title>
      <link>https://fathersit.tistory.com/12</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVqA6D/btrI9l9dfi1/lIzki1AMyFkWGMpq9mkZ3k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVqA6D/btrI9l9dfi1/lIzki1AMyFkWGMpq9mkZ3k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVqA6D/btrI9l9dfi1/lIzki1AMyFkWGMpq9mkZ3k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVqA6D%2FbtrI9l9dfi1%2FlIzki1AMyFkWGMpq9mkZ3k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공격자가 소프트웨어의 의도된 동작을 변경하도록 임의 코드를 삽입하여 소프트웨어가 비정상적으로 동작하도록 하는 보안 약점을 말한다. 코드 삽입은 프로그래밍 언어 자체의 기능에 한해 이뤄진다는 점에서 운영체제 명령어 삽입과 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;취약한 프로그램에서 사용자의 입력 값에 코드가 포함되는 것을 허용할 경우, 공격자는 개발자가 의도하지 않은 코드를 실행하여&amp;nbsp;권한을&amp;nbsp;탈취하거나&amp;nbsp;인증&amp;nbsp;우회,&amp;nbsp;시스템&amp;nbsp;명령어&amp;nbsp;실행&amp;nbsp;등을&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python에서 코드 삽입 공격을 유발할 수 있는 함수로 eval(), exec()등의 함수가 있다. 해당 함수의 인자를 면밀히 검증하지&amp;nbsp;않는&amp;nbsp;경우&amp;nbsp;공격자가&amp;nbsp;전달한&amp;nbsp;코드를&amp;nbsp;그대로&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동적코드를 실행할 수 있는 함수를 사용하지 않는다. 필요 시, 실행 가능한 동적코드를 입력 값으로 받지 않도록, 외부 입력값에 대하여 화이트리스트 방식으로 검증한다. 또는 유효한 문자만 포함하도록 동적 코드에 사용되는 사용자 입력 값을 필터링&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ eval()함수&amp;nbsp;사용&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은&amp;nbsp;안전하지&amp;nbsp;않은&amp;nbsp;예제소스코드로&amp;nbsp;eval()을&amp;nbsp;사용하여&amp;nbsp;사용자로부터&amp;nbsp;입력받은&amp;nbsp;값을&amp;nbsp;실행하여&amp;nbsp;결과를&amp;nbsp;리턴하는&amp;nbsp;예제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;5라인에서 입력 받은 값을 아무런 검증 없이 10라인에서 eval()함수의 인자로 사용하고 있다. 외부 입력값을 검증 없이 사용할 경우 공격자는 Python 코드를 입력하여 라이브러리 로드 및 원격 대화형 쉘 등을 실행할 수도 있다. 만일 message에 공격자가&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;코드를&amp;nbsp;입력&amp;nbsp;하면&amp;nbsp;20초&amp;nbsp;동안&amp;nbsp;응용프로그램이&amp;nbsp;sleep&amp;nbsp;상태에&amp;nbsp;빠질&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;예시)&amp;nbsp;&amp;ldquo;compile(&amp;lsquo;for&amp;nbsp;x&amp;nbsp;in&amp;nbsp;range(1):\n&amp;nbsp;import&amp;nbsp;time\n&amp;nbsp;time.sleep(20)&amp;rsquo;,&amp;rsquo;a&amp;rsquo;,&amp;rsquo;single&amp;rsquo;)&amp;rdquo;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;route(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#외부로&amp;nbsp;입력받은&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용하면&amp;nbsp;안전하지&amp;nbsp;않다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;message&amp;nbsp;=&amp;nbsp;request.POST.get('message',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;eval함수에&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;Python&amp;nbsp;코드가 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;위험하다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ret&amp;nbsp;=&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;eval(message)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'data':ret})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 코드로 변환한 예제이다. 외부 입력값에 Python 코드를 실행할 수 있는 특수 문자 등을 필터링 하여 사전에 검증하는 코드를 추가하면 코드삽입을 완화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 코드는 4라인에서 입력 받은 외부 입력값을 10라인의 eval() 함수의&amp;nbsp;인자&amp;nbsp;값으로&amp;nbsp;사용하기&amp;nbsp;전에&amp;nbsp;9라인에서&amp;nbsp;입력&amp;nbsp;값이&amp;nbsp;영문과&amp;nbsp;숫자만으로&amp;nbsp;입력되었는지&amp;nbsp;검증&amp;nbsp;후&amp;nbsp;사용하도록&amp;nbsp;하고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from django.shortcuts import render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;route(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;message&amp;nbsp;=&amp;nbsp;request.POST.get('message',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자&amp;nbsp;입력을&amp;nbsp;영문,&amp;nbsp;숫자로&amp;nbsp;제한하는&amp;nbsp;예로.&amp;nbsp;특수문자가&amp;nbsp;포함되어 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;있을&amp;nbsp;경우&amp;nbsp;에러&amp;nbsp;메시지를&amp;nbsp;리턴&amp;nbsp;한다. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;message.isalnum(): &lt;br /&gt;ret&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;eval(message)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html',&amp;nbsp;{'data':ret}) &lt;br /&gt;......&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python은 다양한 String Methods를 제공하고 있다. 외부 입력값에 대한 검증이 필요한 경우 적절한 메소드를 사용해야 한다.&amp;nbsp;아래는&amp;nbsp;Python에서&amp;nbsp;제공하는&amp;nbsp;String&amp;nbsp;Methods중&amp;nbsp;일부&amp;nbsp;예시이다. &lt;br /&gt;⦁str.isalpha()&amp;nbsp;:&amp;nbsp;문자열&amp;nbsp;내의&amp;nbsp;모든&amp;nbsp;문자가&amp;nbsp;알파벳이고,&amp;nbsp;적어도&amp;nbsp;하나의&amp;nbsp;문자가&amp;nbsp;존재하는&amp;nbsp;경우&amp;nbsp;True를&amp;nbsp;반환. &lt;br /&gt;⦁str.isdecimal()&amp;nbsp;:&amp;nbsp;문자열&amp;nbsp;내의&amp;nbsp;모든&amp;nbsp;문자가&amp;nbsp;십진수&amp;nbsp;문자이고,&amp;nbsp;적어도&amp;nbsp;하나의&amp;nbsp;문자가&amp;nbsp;존재하는&amp;nbsp;경우&amp;nbsp;True를&amp;nbsp;반환. &lt;br /&gt;⦁str.isdigit() : 문자열 내의 모든 문자가 숫자이고, 적어도 하나의 문자가 존재하는 경우 True를 반환. 십진수 문자와 호환되는&amp;nbsp;위&amp;nbsp;첨자&amp;nbsp;숫자와&amp;nbsp;같은&amp;nbsp;숫자도&amp;nbsp;포함.&amp;nbsp;ex)&amp;nbsp;&amp;lsquo;52&amp;rsquo;&amp;nbsp;는&amp;nbsp;True를&amp;nbsp;반환.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;입력 값 검증 시 외부 입력값이 특정 형식을 따라야 할 경우 정규식을 이용하여 검증을 할 수 있고, Python의 re 라이브러리를&amp;nbsp;사용하여&amp;nbsp;검증&amp;nbsp;가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예로&amp;nbsp;Email&amp;nbsp;형식의&amp;nbsp;입력만&amp;nbsp;받아야&amp;nbsp;한다면&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;정규식으로&amp;nbsp;검증&amp;nbsp;가능하다. &lt;br /&gt;ex)&amp;nbsp;prog&amp;nbsp;=&amp;nbsp;re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ exec()함수&amp;nbsp;사용&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 exec()함수를 사용한 안전하지 않은 코드 예제이다. 4라인에서 입력받은 외부 입력값을 검증 없이 9라인의 exec 함수의 인자로 사용하고 있다. 이 경우 중요 데이터 탈취 및 서버의 권한 탈취, 액세스 거부, 심지어 완전한 호스트 탈취를 유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;request_rest_api(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;function_name&amp;nbsp;=&amp;nbsp;request.POST.get('function_name',&amp;nbsp;'')&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자에게&amp;nbsp;전달받은&amp;nbsp;함수명을&amp;nbsp;검증하지&amp;nbsp;않고&amp;nbsp;실행 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;입력&amp;nbsp;값으로&amp;nbsp;&amp;ldquo;import&amp;nbsp;plaform&amp;nbsp;\n&amp;nbsp;platform.system()&amp;rdquo;&amp;nbsp;등을&amp;nbsp;입력&amp;nbsp;시 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;시스템정보&amp;nbsp;노출&amp;nbsp;위험이&amp;nbsp;있다.&lt;/span&gt; &lt;br /&gt;ret&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;exec('{}()'.format(function_name))&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success',&amp;nbsp;{'data':ret})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 코드로 변환한 예제이다. 우선 외부에서 입력 받는 라이브러리 명을 미리 정의한 화이트리스트에 있는 지를 확인하고&amp;nbsp;리스트에&amp;nbsp;없는&amp;nbsp;경우엔&amp;nbsp;에러&amp;nbsp;페이지를&amp;nbsp;리턴한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;WHITE_LIST&amp;nbsp;=&amp;nbsp;['get_friends_list',&amp;nbsp;'get_address',&amp;nbsp;'get_phone_number']&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;def&amp;nbsp;request_rest_api(request): &lt;br /&gt;function_name&amp;nbsp;=&amp;nbsp;request.POST.get('function_name',&amp;nbsp;'') &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;함수&amp;nbsp;명을&amp;nbsp;화이트리스트로&amp;nbsp;제한 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;if&amp;nbsp;function_name&amp;nbsp;in&amp;nbsp;WHITE_LIST:&lt;/span&gt; &lt;br /&gt;ret&amp;nbsp;=&amp;nbsp;exec('{}()'.format(function_name)) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success',&amp;nbsp;{'data':ret}) &lt;br /&gt;&lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/error',&amp;nbsp;{'error':'허용되지&amp;nbsp;않은&amp;nbsp;함수입니다.'})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/12</guid>
      <comments>https://fathersit.tistory.com/12#entry12comment</comments>
      <pubDate>Mon, 8 Aug 2022 23:20:37 +0900</pubDate>
    </item>
    <item>
      <title>[시큐어코딩 가이드] SQL 삽입</title>
      <link>https://fathersit.tistory.com/11</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqtFku/btrJik1jrtO/0JhXMawQpglH2kk6SYbbz1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqtFku/btrJik1jrtO/0JhXMawQpglH2kk6SYbbz1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqtFku/btrJik1jrtO/0JhXMawQpglH2kk6SYbbz1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqtFku%2FbtrJik1jrtO%2F0JhXMawQpglH2kk6SYbbz1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 입력데이터 검증 및 표현&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해&amp;nbsp;발생되는&amp;nbsp;보안약점으로&amp;nbsp;SQL&amp;nbsp;삽입,&amp;nbsp;크로스사이트&amp;nbsp;스크립트(XSS)&amp;nbsp;등의&amp;nbsp;공격을&amp;nbsp;유발할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SQL 삽입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터베이스(DB)와 연동된 웹 응용프로그램에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및&amp;nbsp;URL&amp;nbsp;입력란에&amp;nbsp;SQL&amp;nbsp;문을&amp;nbsp;삽입하여&amp;nbsp;DB로부터&amp;nbsp;정보를&amp;nbsp;열람하거나&amp;nbsp;조작할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안취약점을&amp;nbsp;말한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;취약한 웹 응용프로그램에서는 사용자로부터 입력된 값을 검증 없이 넘겨받아 동적쿼리(Dynamic Query)를 생성하기 때문에 개발자가 의도하지 않은&amp;nbsp;쿼리가&amp;nbsp;실행되어&amp;nbsp;정보유출에&amp;nbsp;악용될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서는 데이터베이스에 엑세스에 사용되는 다양한 Python 모듈간의 일관성을 장려하기 위해 DB-API를 정의 하고있고 각 데이터베이스마다 별도의 DB 모듈을 이용해 데이터베이스에 엑세스하게 된다. DB-API 외에도, 파이썬에서는 Django,&amp;nbsp;SQLAlchemy,&amp;nbsp;Storm등의&amp;nbsp;ORM을&amp;nbsp;사용하여&amp;nbsp;데이터베이스에&amp;nbsp;엑세스할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python에서 지원하는 다양한 ORM(Object Relational Mapping)을 이용하여 보다 안전하게 DB를 사용할 수 있지만 일부 복잡한 조건의 쿼리문 생성 어려움, 성능저하 등의 이유로 쿼리의 튜닝이 필요한 경우 직접 원시 SQL 실행이 필요한 경우가&amp;nbsp;있다.&amp;nbsp;ORM&amp;nbsp;대신&amp;nbsp;원시&amp;nbsp;쿼리를&amp;nbsp;사용하는&amp;nbsp;경우&amp;nbsp;검증되지&amp;nbsp;않은&amp;nbsp;외부&amp;nbsp;입력값으로&amp;nbsp;인해&amp;nbsp;SQL&amp;nbsp;삽입&amp;nbsp;공격이&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 안전한 코딩 기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DB-API를 사용할 때에는 매개변수화된 쿼리(Parameterized query)를 사용하여 외부 입력값을 바인딩해서 사용하면 SQL&amp;nbsp;삽입&amp;nbsp;공격으로부터&amp;nbsp;안전하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Python에서 많이 사용되는 ORM프레임워크로는 Django의 querySets, SQLAlchemy, Storm등이 있다. ORM 프레임워크는&amp;nbsp;내부적으로&amp;nbsp;사용되는&amp;nbsp;쿼리&amp;nbsp;모든&amp;nbsp;곳에서&amp;nbsp;매개변수화된&amp;nbsp;명령문을&amp;nbsp;사용하므로&amp;nbsp;SQL&amp;nbsp;삽입&amp;nbsp;공격으로부터&amp;nbsp;보호된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;ORM 프레임워크의 원시 SQL을 사용할 경우에도 안전하게 사용하려면 외부 입력 값을 매개변수화된 쿼리문의 바인딩 변수로&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;코드예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ DB-API&amp;nbsp;사용&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 MySql, PostgreSQL의 DB-API를 사용하여 입력 값을 받아서 처리 하는 안전하지 않은 코드이다. 이 경우에는 외부 입력값을 8, 9 라인에서 입력 받아 변수 name과 content_id에 할당했다. 12 ~ 15라인에서는 외부에서 입력 받은 name과 content_id값을 검증 없이 쿼리문의 인자 값으로 사용하는데 단순 문자열 결합을 통해 쿼리를 생성하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 경우 content_id 값으로 &amp;lsquo;a&amp;rsquo; or &amp;lsquo;a&amp;rsquo; = &amp;lsquo;a와 같은 공격 문자열을 입력하면 조건 절 content_id = &amp;lsquo;a&amp;rsquo; or &amp;lsquo;a&amp;rsquo; = &amp;lsquo;a&amp;rsquo;로 바뀌고, 그&amp;nbsp;결과&amp;nbsp;board&amp;nbsp;테이블&amp;nbsp;전체&amp;nbsp;레코드의&amp;nbsp;name&amp;nbsp;컬럼이&amp;nbsp;공격자로부터&amp;nbsp;입력&amp;nbsp;받은&amp;nbsp;name의&amp;nbsp;값으로&amp;nbsp;변경된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 240px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;update_board(request): &lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;dbconn.cursor()&amp;nbsp;as&amp;nbsp;curs: &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력받은&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;안전하지&amp;nbsp;않다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;content_id&amp;nbsp;=&amp;nbsp;request.POST.get('content_id',&amp;nbsp;'')&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;검증되지&amp;nbsp;않은&amp;nbsp;입력으로&amp;nbsp;부터&amp;nbsp;동적으로&amp;nbsp;쿼리문&amp;nbsp;생성&amp;nbsp;&lt;/span&gt;&lt;br /&gt;sql_query&amp;nbsp;=&amp;nbsp;&quot;update&amp;nbsp;board&amp;nbsp;set&amp;nbsp;name='&quot;&amp;nbsp;+&amp;nbsp;name&amp;nbsp;+&amp;nbsp;&quot;'&amp;nbsp;where&amp;nbsp;content_id='&amp;ldquo;&amp;nbsp;+&amp;nbsp;content_id&amp;nbsp;+&amp;nbsp;&quot;'&quot;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값이&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;쿼리로&amp;nbsp;수행되어&amp;nbsp;안전하지&amp;nbsp;않다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;curs.execute(sql_query)&lt;/span&gt; &lt;br /&gt;curs.commit() &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 이를 안전한 코드로 변환한 예제이다. 7, 8라인에서 입력받은 외부 입력값을 그대로 사용하지 않고, 15라인의 execute()메서드의 두 번째 인자 값으로 바인딩 해서 쿼리 문을 실행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;11라인과 같이 매개변수 바인딩을 통해 execute() 함수를 호출하면 공격자가 쿼리를 변조하는 값을 삽입하더라도 해당 값이 바인딩된 매개변수의 값으로만 사용되지 때문에&amp;nbsp;안전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;update_board(request): &lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;with&amp;nbsp;dbconn.cursor()&amp;nbsp;as&amp;nbsp;curs: &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'') &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;content_id&amp;nbsp;=&amp;nbsp;request.POST.get('content_id',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력값으로&amp;nbsp;부터&amp;nbsp;안전한&amp;nbsp;매개변수&amp;nbsp;화된&amp;nbsp;쿼리를&amp;nbsp;생성&amp;nbsp;한다.&lt;/span&gt; &lt;br /&gt;sql_query&amp;nbsp;=&amp;nbsp;'update&amp;nbsp;board&amp;nbsp;set&amp;nbsp;name=%s&amp;nbsp;where&amp;nbsp;content_id=%s'&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;사용자의&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;매개변수&amp;nbsp;화된&amp;nbsp;쿼리에&amp;nbsp;바인딩&amp;nbsp;하여&amp;nbsp;실행되므로 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;안전하다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;curs.execute(sql_query,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;(name,&amp;nbsp;content_id))&lt;/span&gt; &lt;br /&gt;curs.commit() &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/success.html')&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQLite DB-API 사용에서도 동일하게 정적인 쿼리문을 사전에 생성하고 사용자 입력을 바인딩 하여 안전하게 사용하여야 한다. SQLite에서 매개변수 화된 쿼리(Parameterized Query)를 만들기 위해 &amp;ldquo;?&amp;rdquo;를 Placeholder로 사용하거나 &amp;ldquo;:name&amp;rdquo; 처럼&amp;nbsp;Named&amp;nbsp;Placeholder를&amp;nbsp;사용하는&amp;nbsp;방법&amp;nbsp;2가지가&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ ORM&amp;nbsp;사용&amp;nbsp;예제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Django의 querysets는 쿼리 매개변수화를 사용하여 쿼리를 구성하기 때문에 SQL 삽입 공격으로부터 보호된다. 부득이 하게 원시 SQL, 또는 사용자 정의 SQL을 사용할 경우에도 외부 입력값을 매개변수화된 쿼리의 바인딩 변수로 사용하여야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;아래는 Django의 원시 SQL을 사용하는 예제이다. Django의 ORM 프레임워크는 원시 SQL 쿼리를 수행하기 위해 Manager.raw() 기능을 제공한다. 다음은 안전하지 않은 코드로 6라인에서 입력받은 외부 입력값을 10라인의 쿼리문 생성에 문자열 조합으로 사용하여 쿼리문의&amp;nbsp;구조를&amp;nbsp;만들고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 260px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;안전하지 않은 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; height: 240px;&quot;&gt;from django.shortcuts import render &lt;br /&gt;from&amp;nbsp;app.models&amp;nbsp;import&amp;nbsp;Member&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;member_search(request): &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;가져온다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;받은&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;쿼리문&amp;nbsp;생성에&amp;nbsp;사용하여 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;# 안전하지 않다.&lt;/span&gt;&lt;br /&gt;query=&amp;ldquo;select&amp;nbsp;*&amp;nbsp;from&amp;nbsp;member&amp;nbsp;where&amp;nbsp;name=&amp;lsquo;&amp;rdquo;&amp;nbsp;+&amp;nbsp;name&amp;nbsp;+&amp;nbsp;&amp;ldquo;&amp;rsquo;&amp;rdquo;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;사용한&amp;nbsp;쿼리문을&amp;nbsp;raw()함수로&amp;nbsp;실행하면 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;#&amp;nbsp;안전하지&amp;nbsp;않다.&lt;/span&gt; &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;Member.objects.raw(query)&lt;/span&gt; &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/member_list.html',&amp;nbsp;{'member_list':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음은 안전한 코드 예제로 Django에서 원시코드를 실행할 경우에도 매개변수화된 쿼리를 사용하고 params 인수를 사용하여&amp;nbsp;raw()&amp;nbsp;함수의&amp;nbsp;바인딩&amp;nbsp;변수로&amp;nbsp;사용하여야&amp;nbsp;한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;9라인에서 쿼리문 생성을 매개변수화된 쿼리로 생성하고 6라인에서 입력받은&amp;nbsp;외부&amp;nbsp;입력값을&amp;nbsp;10라인의&amp;nbsp;raw()메소드에서&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;인자의&amp;nbsp;바인딩변수로&amp;nbsp;사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;안전한 코드의 예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;from&amp;nbsp;django.shortcuts&amp;nbsp;import&amp;nbsp;render &lt;br /&gt;from&amp;nbsp;app.models&amp;nbsp;import&amp;nbsp;Member&lt;br /&gt;&lt;br /&gt;def&amp;nbsp;member_search(request): &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부로부터&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;가져온다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;name&amp;nbsp;=&amp;nbsp;request.POST.get('name',&amp;nbsp;'')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;외부&amp;nbsp;입력&amp;nbsp;값을&amp;nbsp;raw()함수&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;바인딩&amp;nbsp;변수로&amp;nbsp;사용하여&amp;nbsp;쿼리&amp;nbsp;구조가 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;변경되지&amp;nbsp;않도록&amp;nbsp;한다.(list&amp;nbsp;형은&amp;nbsp;%s,&amp;nbsp;dictionary&amp;nbsp;형은&amp;nbsp;%(key)s를&amp;nbsp;사용) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;query='select&amp;nbsp;*&amp;nbsp;from&amp;nbsp;member&amp;nbsp;where&amp;nbsp;name=%s'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;#&amp;nbsp;인자화된&amp;nbsp;쿼리문을&amp;nbsp;사용하여&amp;nbsp;raw()함수를&amp;nbsp;사용하여&amp;nbsp;안전하다.&lt;/span&gt; &lt;br /&gt;data&amp;nbsp;=&amp;nbsp;Member.objects.raw(query,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;[name]&lt;/span&gt;) &lt;br /&gt;return&amp;nbsp;render(request,&amp;nbsp;'/member_list.html',&amp;nbsp;{'member_list':data})&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/11</guid>
      <comments>https://fathersit.tistory.com/11#entry11comment</comments>
      <pubDate>Mon, 8 Aug 2022 23:17:59 +0900</pubDate>
    </item>
    <item>
      <title>시큐어코딩 가이드(시큐어 코딩의 필요성)</title>
      <link>https://fathersit.tistory.com/10</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공격자의 초점이 지속적으로 애플리케이션 계층을 향해 이동함에 따라 소프트웨어 자원보호가 중요해졌다. 최근 발생되는 인터넷상 공격시도의 약 75%는 소프트웨어보안취약점을 악용하는 것으로, 특히 외부에 공개되어 불특정다수를 대상으로 사용자 정보를 처리하는 웹 애플리케이션의 취약점으로 인해 중요정보가 유출되는 침해사고가 빈번하게 발생되고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안강화를 위해 구축해놓은 침입차단시스템과 같은 보안장비로 응용프로그램 취약점에 대한 공격을 완벽히 방어하는 것은 불가능하다. 소프트웨어의 개발보안 미적용으로 제품 출시 때 수정 시 설계 단계보다 30배, 구현 단계 보다 20배가 넘는 수정비용이 필요&amp;nbsp;한&amp;nbsp;걸로&amp;nbsp;조사되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;국내의 경우, 2009년부터 전자정부서비스 개발단계에서 소프트웨어 보안약점을 진단하여 제거하는 소프트웨어 개발 보안(시큐어코딩) 관련 연구를 진행하면서, 2012년까지 전자정부지원사업 등을 대상으로 소프트웨어 보안약점 시범진단을 수행하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이러한 소프트웨어 보안약점 제거&amp;middot;조치 성과에 따라 2012년 6월에 행정안전부 &amp;lsquo;정보시스템 구축&amp;middot;운영 지침&amp;rsquo;이 개정&amp;middot;고시됨으로써 전자정부서비스 개발 시 적용토록 의무화 되었다. 2019년 6월에는 소프트웨어 개발 보안의 법적 근거를 담은 소프트웨어진흥법 개정안이 발의되었고 2020년 12월 10일에 시행됨에 따라 민간분야에서의 소프트웨어 개발보안 영역이&amp;nbsp;확대되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Python&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 파이썬 시큐어코딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KvMlq/btrJilTqyon/IG6ZPpNmZmpHF9pyKcaHw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KvMlq/btrJilTqyon/IG6ZPpNmZmpHF9pyKcaHw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KvMlq/btrJilTqyon/IG6ZPpNmZmpHF9pyKcaHw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKvMlq%2FbtrJilTqyon%2FIG6ZPpNmZmpHF9pyKcaHw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;874&quot; height=&quot;792&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그래밍 언어의 종류가 다양해짐에 따라 민간에서 타 언어에 대한 시큐어코딩 가이드에 대한 수요가 늘어났다. 이에 민간에서 가장 많이 활용되고 있는 언어 중 선호도가 가장 높은 Python 언어에 대한 시큐어코딩 가이드를 소개하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python은 1991년에 발표된 고급언어로 플랫폼에 독립적이며 인터프리터식, 객체지향적, 동적 타이핑(dynamically typing)&amp;nbsp;대화형&amp;nbsp;언어이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다양한 플랫폼에서 쓸 수 있고, 라이브러리(모듈)가 풍부하여 대학을 비롯한 여러 교육 기관, 연구 기관 및 산업계에서 이용이 증가하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최근 웹 개발 이외에도 그래픽, 머신러닝 업계에서 선호하는 언어로 최근은 C,&amp;nbsp;JAVA를&amp;nbsp;제치고&amp;nbsp;선호도&amp;nbsp;1위에&amp;nbsp;오르기도&amp;nbsp;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>정보보안/시큐어코딩 가이드</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/10</guid>
      <comments>https://fathersit.tistory.com/10#entry10comment</comments>
      <pubDate>Mon, 8 Aug 2022 22:28:53 +0900</pubDate>
    </item>
    <item>
      <title>블록체인 관련 용어 정의 - 3</title>
      <link>https://fathersit.tistory.com/9</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DJYcn/btrJaWgZAkB/CyzP997eK3WvsNx8xk8O90/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DJYcn/btrJaWgZAkB/CyzP997eK3WvsNx8xk8O90/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DJYcn/btrJaWgZAkB/CyzP997eK3WvsNx8xk8O90/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDJYcn%2FbtrJaWgZAkB%2FCyzP997eK3WvsNx8xk8O90%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;940&quot; height=&quot;600&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;블록체인 관련 용어&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 자기&amp;nbsp;주권&amp;nbsp;신원&amp;nbsp;self-sovereign&amp;nbsp;identity&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;기존 신원 확인 방식과 달리 분산 네트워크 기술을 활용하여 중앙 시스템에 의해 통제되지 않으며 개개인이 자신의 정보에 완전한 통제권을 갖도록 하는&amp;nbsp;기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 재전송&amp;nbsp;공격&amp;nbsp;replay&amp;nbsp;attack&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;이전에&amp;nbsp;전송된&amp;nbsp;유효한&amp;nbsp;메시지를&amp;nbsp;다시&amp;nbsp;사용하는&amp;nbsp;공격&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 전자&amp;nbsp;서명&amp;nbsp;digital&amp;nbsp;signature&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서명자를 확인하고 서명자가 해당 전자 문서1)에 서명을 하였음을 나타내는데 이용하기 위하여 해당 전자 문서에 첨부되거나 논리적으로 결합된 전자적 형태의 정보. 전자 서명의 생성과 검증을 위해 각각 서명자가 가진 개인키와 해당 개인키에 대응하는&amp;nbsp;공개키를&amp;nbsp;사용함으로써,&amp;nbsp;서명자의&amp;nbsp;확인과&amp;nbsp;부인&amp;nbsp;방지가&amp;nbsp;가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 중간자&amp;nbsp;공격&amp;nbsp;man-in-the-middle&amp;nbsp;attack&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;통신하고 있는 두 당사자 사이에 끼어들어 당사자들이 교환하는 통신 내용을&amp;nbsp;바꾸거나&amp;nbsp;도청하는&amp;nbsp;공격&amp;nbsp;기법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■&lt;span&gt; 최초&amp;nbsp;블록&amp;nbsp;genesis&amp;nbsp;block&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인&amp;nbsp;시스템의&amp;nbsp;초기&amp;nbsp;상태를&amp;nbsp;기록한&amp;nbsp;블록체인의&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;블록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 크리덴셜&amp;nbsp;credential&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;신원이나&amp;nbsp;자격을&amp;nbsp;주장하면서&amp;nbsp;증거로&amp;nbsp;제출된&amp;nbsp;데이터&amp;nbsp;집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 탈중앙화&amp;nbsp;애플리케이션&amp;nbsp;DApp,&amp;nbsp;decentralized&amp;nbsp;application&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인 솔루션에 참여하는 개체가 블록체인 시스템을 활용할 수 있도록 블록체인&amp;nbsp;시스템상에서&amp;nbsp;운영되는&amp;nbsp;애플리케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 트랜잭션&amp;nbsp;transaction&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자산의&amp;nbsp;이동&amp;nbsp;또는&amp;nbsp;생성과&amp;nbsp;같이&amp;nbsp;블록체인에서&amp;nbsp;발생하는&amp;nbsp;이벤트의&amp;nbsp;기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 하드웨어&amp;nbsp;보안&amp;nbsp;모듈&amp;nbsp;HSM,&amp;nbsp;Hardware&amp;nbsp;Security&amp;nbsp;Module&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개인키 등의 비밀 정보를 안전하게 저장, 보관할 수 있고 기기 내부에 프로세스 및 암호 연산 장치가 있어 전자 서명 키 생성, 전자 서명 생성 &amp;middot; 검증 등이 가능한 하드웨어 장치. 기기 내부에 저장된 전자 서명 개인키 등 비밀 정보는 장치 외부로 복사 또는 재생성되지 않으며 스마트카드, 유에스비(USB) 토큰 등 다양한 형태로 제작 및&amp;nbsp;구현이&amp;nbsp;가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 합의&amp;nbsp;consensus&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든&amp;nbsp;참여자가&amp;nbsp;하나의&amp;nbsp;결과에&amp;nbsp;동의하는&amp;nbsp;것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 합의&amp;nbsp;프로토콜&amp;nbsp;consensus&amp;nbsp;protocol&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 참여자가 합의에 도달하기 위해 약속한 규칙과 절차. 일반적으로 블록체인 기술에서는 블록체인에 추가할 블록을 결정하는 규칙과 절차를&amp;nbsp;의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 해시&amp;nbsp;함수&amp;nbsp;hash&amp;nbsp;function&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;임의 길이의 메시지를 일정 길이의 출력값으로 압축하는 알고리즘. 해시 함수의 출력값을 해시값 (hash value)이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 허가형&amp;nbsp;블록체인&amp;nbsp;permissioned&amp;nbsp;blockchain&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인을 유지 관리하는 합의, 계정 관리 등의 절차에 참여하려면 사전&amp;nbsp;허가가&amp;nbsp;필요한&amp;nbsp;블록체인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 협정&amp;nbsp;세계시&amp;nbsp;UTC,&amp;nbsp;Coordinated&amp;nbsp;Universal&amp;nbsp;Time&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;국제&amp;nbsp;협정에&amp;nbsp;따라&amp;nbsp;국제&amp;nbsp;사회가&amp;nbsp;사용하는&amp;nbsp;과학적&amp;nbsp;시간의&amp;nbsp;표준&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ DTLS&amp;nbsp;Datagram&amp;nbsp;Transport&amp;nbsp;Layer&amp;nbsp;Security&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TLS를 UDP(User Datagram Protocol) 통신상에서 활용할 수 있도록 수정한 프로토콜. DTLS는 데이터 전송에 대한 신뢰성을 보장할 수 있는 전송계층 프로토콜 (예: TCP)상에서 동작하도록 설계된 보안 프로토콜인 TLS를 수정하여, 데이터 전송 신뢰성을 보장할 수 없는 UDP 통신에 대한 TLS 수준의 정보보호 서비스를 제공하기 위해 설계되었다. DTLS는 UDP의 통신 특성(데이터 누락, 순서 비보장 등)을 반영하여 TLS를&amp;nbsp;최소한의&amp;nbsp;수준으로&amp;nbsp;수정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ TLS&amp;nbsp;Transport&amp;nbsp;Layer&amp;nbsp;Security&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TCP/IP 계층의 서버-클라이언트 통신에 대해 기밀성, 무결성, 인증과 같은 정보보호 서비스를 제공하는 프로토콜. TLS는 cipher suite와 키 교환 및 사용자 인증을 수행하는 핸드셰이크 단계 (handshake layer)와 데이터 암호화 및 메시지 인증을 수행하는 레코드 단계(record layer)로 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ X.509&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ITU-T 표준으로 인증서 구조 명세와 인증 서비스 활용을 위한 관리 메커니즘을&amp;nbsp;제시하는&amp;nbsp;공개키&amp;nbsp;기반&amp;nbsp;구조(PKI)&amp;nbsp;프레임워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/블록체인</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/9</guid>
      <comments>https://fathersit.tistory.com/9#entry9comment</comments>
      <pubDate>Mon, 8 Aug 2022 21:50:20 +0900</pubDate>
    </item>
    <item>
      <title>블록체인 관련 용어 정의 - 2</title>
      <link>https://fathersit.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q9d4R/btrJclAqygk/IwGkWK2Ka6biUfGRXj1xJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q9d4R/btrJclAqygk/IwGkWK2Ka6biUfGRXj1xJ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q9d4R/btrJclAqygk/IwGkWK2Ka6biUfGRXj1xJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ9d4R%2FbtrJclAqygk%2FIwGkWK2Ka6biUfGRXj1xJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;940&quot; height=&quot;600&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; border-width: 10px; padding: 3px 5px; border-left-style: solid; border-left-color: #000000; letter-spacing: 1px; margin: 5px 0px; line-height: 1.2;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;블록체인 관련 용어&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 블록체인&amp;nbsp;오라클&amp;nbsp;blockchain&amp;nbsp;oracle&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;블록체인 시스템 외부에서 생성된 데이터를 이용하여 블록체인에 정보를 제공하는&amp;nbsp;서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 블록체인&amp;nbsp;SW&amp;nbsp;플랫폼&amp;nbsp;blockchain&amp;nbsp;software&amp;nbsp;platform&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;블록체인 노드가 블록체인 시스템에 참여할 수 있도록 제공되는 프로세스, 저장소, 통신 기능의 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 비잔틴&amp;nbsp;장애&amp;nbsp;허용&amp;nbsp;BFT,&amp;nbsp;Byzantine&amp;nbsp;Fault&amp;nbsp;Tolerance&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;분산 환경에서 비잔틴 장애(단순 장애뿐만 아니라 담합, 거짓 응답 등 프로토콜의 규칙을 의도적으로 위반하는 행위)가 발생해도 정상적으로 합의를 도출할 수 있는 성질. 단, 전체 분산 개체 중 1/3 이상의 비잔틴 장애를 허용하는 프로토콜은 존재할&amp;nbsp;수&amp;nbsp;없다는&amp;nbsp;것이&amp;nbsp;증명되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 비허가형&amp;nbsp;블록체인&amp;nbsp;permissionless&amp;nbsp;blockchain&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인을 유지ㆍ관리하는 합의 절차에 허가 없이 누구나 참여할 수 있는 블록체인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■&lt;span&gt; 서비스&amp;nbsp;거부&amp;nbsp;공격&amp;nbsp;denial&amp;nbsp;of&amp;nbsp;service&amp;nbsp;attack&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정보&amp;nbsp;시스템에&amp;nbsp;과도한&amp;nbsp;부하를&amp;nbsp;일으켜&amp;nbsp;시스템의&amp;nbsp;데이터나&amp;nbsp;자원을&amp;nbsp;정당한 &lt;br /&gt;사용자가&amp;nbsp;적절한&amp;nbsp;대기&amp;nbsp;시간&amp;nbsp;내에&amp;nbsp;사용하는&amp;nbsp;것을&amp;nbsp;방해하는&amp;nbsp;공격&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 스마트&amp;nbsp;컨트랙트&amp;nbsp;smart&amp;nbsp;contract&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 실행 결과가 블록체인에 기록되는 블록체인 시스템상의 컴퓨터 프로그램&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 식별자&amp;nbsp;ID,&amp;nbsp;Identifier&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서로&amp;nbsp;다른&amp;nbsp;개체를&amp;nbsp;구별할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 신뢰&amp;nbsp;실행&amp;nbsp;환경&amp;nbsp;TEE,&amp;nbsp;Trusted&amp;nbsp;Execution&amp;nbsp;Environment&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;독립된 보안 영역이 제공하는 안전한 실행 환경. 일반 영역과 보안 영역이 따로 분리된 프로세서에서, 보안 영역에는 생체 정보, 결제 정보, 기업 보안 문서 등의 중요한 정보가 저장된다. 일반 영역과의 정보&amp;nbsp;교환이&amp;nbsp;통제되고&amp;nbsp;보안&amp;nbsp;소프트웨어가&amp;nbsp;안전하게&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 신뢰&amp;nbsp;플랫폼&amp;nbsp;모듈&amp;nbsp;TPM,&amp;nbsp;Trusted&amp;nbsp;Platform&amp;nbsp;Module&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;암호화된 키, 패스워드, 디지털 인증서 등을 저장하는 안전한 저장공간을&amp;nbsp;제공하는&amp;nbsp;보안&amp;nbsp;모듈&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 암호모듈&amp;nbsp;검증제도&amp;nbsp;KCMVP,&amp;nbsp;Korean&amp;nbsp;Cryptographic&amp;nbsp;Module&amp;nbsp;Validation&amp;nbsp;Program&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;행정기관 등 국가 &amp;middot; 공공기관 정보통신망에서 소통되는 자료 중 중요 정보의 보호를 위해 사용되는 암호모듈의 안전성과 구현 적합성을 검증하는&amp;nbsp;제도&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 오프체인&amp;nbsp;off-chain&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인 시스템과 연관이 있지만, 블록체인 시스템 외부에 위치, 수행, 또는&amp;nbsp;운영되는&amp;nbsp;특성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 온라인&amp;nbsp;인증서&amp;nbsp;상태&amp;nbsp;프로토콜&amp;nbsp;OCSP,&amp;nbsp;Online&amp;nbsp;Certificate&amp;nbsp;Status&amp;nbsp;Protocol&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특정 인증서의 현재(폐지) 상태를 실시간으로 인증 기관(CA, Certificate Authority)을&amp;nbsp;통해&amp;nbsp;확인하는&amp;nbsp;프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 온체인&amp;nbsp;on-chain&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블록체인&amp;nbsp;시스템&amp;nbsp;내부에&amp;nbsp;위치,&amp;nbsp;수행,&amp;nbsp;또는&amp;nbsp;운영되는&amp;nbsp;특성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 완결성&amp;nbsp;finality&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;원장에 기록된 트랜잭션이 삭제되지 않음을 보장하는 성질. 블록체인 기술에서의 완결성은 트랜잭션의 묶음인 블록이 삭제되지 않는다는 것을&amp;nbsp;의미한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 원장&amp;nbsp;ledger&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;완결성과&amp;nbsp;불변성이&amp;nbsp;요구되는&amp;nbsp;트랜잭션의&amp;nbsp;기록을&amp;nbsp;위한&amp;nbsp;저장소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 응용&amp;nbsp;프로그래밍&amp;nbsp;인터페이스&amp;nbsp;API,&amp;nbsp;Application&amp;nbsp;Programming&amp;nbsp;Interface&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;응용 소프트웨어와 소프트웨어 플랫폼 사이에 존재하며, 플랫폼상에서 실행하는 애플리케이션 개발을 용이하게 하는 소프트웨어 라이브러리 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■ 인증&amp;nbsp;authentication&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개체의 식별 정보의 유효성을 확인하거나 주어진 데이터의 출처를 확인할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;특성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■&lt;span&gt; 인증서&amp;nbsp;certificate&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전자 서명을 생성하기 위하여 이용하는 전자적 정보가 해당 사용자에게 유일하게&amp;nbsp;속한다는&amp;nbsp;사실&amp;nbsp;등을&amp;nbsp;확인하고&amp;nbsp;이를&amp;nbsp;증명하는&amp;nbsp;전자적&amp;nbsp;정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;■&lt;span&gt;&lt;span&gt; 인증서&amp;nbsp;폐기&amp;nbsp;목록&amp;nbsp;CRL,&amp;nbsp;Certificate&amp;nbsp;Revocation&amp;nbsp;List&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인증서를 발급한 인증 기관(CA)이 특정 공개 저장소에 관리하는 &amp;ldquo;현재&amp;rdquo; 폐지된&amp;nbsp;인증서&amp;nbsp;목록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/블록체인</category>
      <author>아빠아이티</author>
      <guid isPermaLink="true">https://fathersit.tistory.com/8</guid>
      <comments>https://fathersit.tistory.com/8#entry8comment</comments>
      <pubDate>Mon, 8 Aug 2022 21:48:22 +0900</pubDate>
    </item>
  </channel>
</rss>