💡 비대칭키 알고리즘 (= 공개키 암호화 방식)
▪ 암호화에 사용하는 키와 복호화에 사용하는 키가 상이
▪ 개인키와 공개키 쌍으로 구성
개인키로 암호화 → 공개키로 복호화 가능
공개키로 암호화 → 개인키로 복호화 가능
은행의 공개키로 암호화 [나의 개인키로 서명(송금 데이터)]
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
| |
+-- 기밀성 보장 +-- 부인방지
===> 은행의 개인키로 복호화
===> 나의 공개키로 검증
===> 데이터
수신자의 공개키로 암호화 [송신자의 개인키 암호화(데이터)]
===> 수신자의 개인키로 복호화
===> 송신자의 공개키로 복호화
쿠키의 유효 기간 또는 지속 시간을 필요 이상으로 길게 잡는 경우
🔍 쿠키를 안전하게 운용하는 방법
💡 <장고의 경우>
Response.set_cookie() 메서드를 이용해 쿠키 속성을 설정하는 것이 가능def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None):
🔍 안전한 해시 생성 방법
외부에서 가져 온 코드를 검증·제한하지 않고 사용(실행)
인증 → 사용자가 맞는지 확인하는 과정
login?id=abcd&pw=????
ID: abcd ~~~~~~~~~~~~~~~~~~~~~~~~~> 전달된 ID와 PW와 일치하는
데이터가 존재하는지 확인
PW: ???? <~~~~~~~~~~~~~~~~~~~~~~~~~
일치하는 경우에는 인증 후 보여지는 내용(main),
일치하지 않는 경우에는 오류 메시지가 출력
login?id=abcd&pw=????
~~~~
들어갈 수 있는 모든 경우를 대입해서 요청 → main 페이지가 나올 때까지
→ 인증 기능을 악용하면 패스워드를 찾는 기능으로 활용 가능
→ 시도 횟수를 제한하고, 인증 정보 이외의 추가적 정보를 전달해야 인증을 처리하도록 해야 함
~~~~~~~~~~~
CAPTCHA → 자동화된 요청 방해
= 사용자와의 인터렉션을 통해 요청 처리
동시 또는 거의 동시에 여러 코드 수행을 지원하는 병렬 시스템이나 하나 이상의 프로세스가 동작되는 환경에서 시간 및 상태를 부적절하게 관리하여 발생할 수 있는 보안 약점
재귀 함수 구현 시 귀납 조건(base case, 재귀문을 빠져 나가는 조건)을 구현하지 않으면 무한한 재귀에 빠지게 되고 함수의 반환 주소를 가지고 있는 콜 스택의 한계를 초과해 오류 또는 장애가 발생할 수 있음
def fatorial(num): → 귀납 조건이 구현되어 있지 않아 무한 재귀에 빠지게 됨
return num * fatorial(num - 1)
~~~~~~~~~~~~~~~~~ 재귀 호출이 발생
def fatorial(num):
if num <= 1: → 재귀문을 빠져 나오는 조건 = 귀납 조건
return 1
return num * fatorial(num - 1)
에러를 처리하지 않거나 불충분하게 처리하여 에러 정보에 중요정보(시스템 내부정보 등)가 포함될 때 발생할 수 있는 보안 약점
▪ 오류 메시지를 통한 시스템 정보노출
타입 변환 오류, 자원(메모리 등)의 부적절한 반환 등과 같이 개발자가 범할 수 있는 코딩 오류로 인해 유발되는 보안 약점
중요한 데이터 또는 기능성을 불충분하게 캡슐화하거나 잘못 사용함으로써 발생하는 보안 약점으로 정보 노출, 권한 문제 등이 발생
💻 pybo\views.py
import time
class UserInfo:
user_id = ''
def __init__(self, user_id):
self.user_id = user_id
pass
def __str__(self):
return self.user_id
def hello_user(request, user_id):
# 요청 파라미터로 전달된 값을 클래스 변수에 설정
UserInfo.user_id = user_id
# 다른 내부 처리를 묘사 (3초 딜레이)
time.sleep(3)
return render(request, 'pybo/success.html',
{ 'data': f'Hello, {UserInfo.user_id}!!!' })
~~~~~~~~~~~~~~~~
# 클래스 변수를 사용
💻 pybo\urls.py
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name="detail"),
path('answer/create/<int:question_id>', views.answer_create, name='answer_create'),
path('question/create/', views.question_create, name='question_create'),
path('download/', views.download, name='download'),
path('execute/app/<str:app_name>', views.execute_app, name='execute_app'),
path('execute/cmd/', views.execute_cmd, name='execute_cmd'),
path('execute/xml/', views.execute_xml, name='execute_xml'),
path('get/site/', views.get_site, name='get_site'),
path('get/userinfo/', views.make_user_message, name='make_user_message'),
path('hello/user/<str:user_id>', views.hello_user, name='hello_user'),
]
💻 동작을 확인
💻 거의 동시에 요청하는 경우 요청 파라미터의 값과 관계 없이 마지막에 요청한 값이 사용되는 것을 확인
💻 클래스 변수를 사용하지 말고 해당 클래스의 인스턴스를 생성해서 사용하는 것으로 변경
def hello_user(request, user_id):
# UserInfo 클래스의 인스턴스를 생성해 user 변수에 할당
user = UserInfo(user_id)
time.sleep(3)
return render(request, 'pybo/success.html',
{ 'data': f'Hello, {user.user_id}!!!' })
~~~~~~~~~~~~
# 인스턴스의 변수값 사용
💻 정상적으로 동작하는 것을 확인할 수 있음
🔍 디버그 코드의 특징
▪ 잘못 구현된 setter 메서드의 문제
💻 c:\python\project\mysite\sample.py
class UserInfo:
__user_secrets__ = []
# 클래스 내부의 값을 반환하는 메서드 → GETTER
def get_user_secrets(self):
return self.__user_secrets__
# 외부에서 클래스 내부에 값을 설정하는 메서드 ==> SETTER
def set_user_secrets(self, user_secrets):
# 외부에서 전달값 주소가 내부 주소로 사용
self.__user_secrets__ = user_secrets
def __str__(self):
return str(self.__user_secrets__)
u1 = [ "홍길동", 23, "hong@test.com" ]
u2 = UserInfo()
u2.set_user_secrets(u1)
print(u1)
print(u2)
print("*" * 40)
u1[0] = "신길동"
print(u1)
print(u2)
💻 실행 결과 출력
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['신길동', 23, 'hong@test.com'] # u1의 내용을 바꾸면 u2 객체 내부의 값도 변경
['신길동', 23, 'hong@test.com'] u1의 값과 같은 값을 공유
💻 외부에서 전달하는 리스트의 값을 복사하는 방식으로 변경
class UserInfo:
__user_secrets__ = []
# 클래스 내부의 값을 반환하는 메서드 → GETTER
def get_user_secrets(self):
return self.__user_secrets__
# 외부에서 클래스 내부에 값을 설정하는 메서드 → SETTER
def set_user_secrets(self, user_secrets):
# 값을 복사하도록 수정
self.__user_secrets__ = user_secrets[:]
def __str__(self):
return str(self.__user_secrets__)
u1 = [ "홍길동", 23, "hong@test.com" ]
u2 = UserInfo()
u2.set_user_secrets(u1)
print(u1)
print(u2)
print("*" * 40)
u1[0] = "신길동"
print(u1)
print(u2)
💻 실행 결과
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['신길동', 23, 'hong@test.com'] # u1의 값은 변경되었으나,
['홍길동', 23, 'hong@test.com'] # u2의 값은 유지되는 것을 확인할 수 있음
▪ 잘못 구현된 getter 메서드의 문제
💻 c:\python\project\mysite\sample.py
class UserInfo:
__user_secrets__ = []
# 클래스 내부의 값을 반환하는 메서드 → GETTER
def get_user_secrets(self):
return self.__user_secrets__ → 내부 리스트의 주소 반환
# 외부에서 클래스 내부에 값을 설정하는 메서드 → SETTER
def set_user_secrets(self, user_secrets):
self.__user_secrets__ = user_secrets[:]
def __str__(self):
return str(self.__user_secrets__)
u1 = [ "홍길동", 23, "hong@test.com" ]
u2 = UserInfo()
u2.set_user_secrets(u1)
print(u1)
print(u2)
print("*" * 40)
u1[0] = "신길동"
print(u1)
print(u2)
print("*" * 40)
# 인스턴스 내부에서 반환한 주소를 사용, 같은 주소를 공유
u3 = u2.get_user_secrets()
print(u2)
print(u3)
print("*" * 40)
# 인스턴스 외부에서 값을 변경하면 인스턴스 내부도 값이 변경
# 인스턴스 내부의 값이 인스턴스 외부에서 제어(변경)될 수 있음
u3[0] = "고길동"
print(u2)
print(u3)
💻 실행 결과
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['신길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['고길동', 23, 'hong@test.com']
['고길동', 23, 'hong@test.com']
💻 내부의 리스트 변수를 외부로 전달할 때 리스트의 값이 전달되도록 수정
class UserInfo:
__user_secrets__ = []
# 클래스 내부의 값을 반환하는 메서드 → GETTER
def get_user_secrets(self):
return self.__user_secrets__[:] → 내부의 값을 반환하도록 수정
# 외부에서 클래스 내부에 값을 설정하는 메서드 → SETTER
def set_user_secrets(self, user_secrets):
self.__user_secrets__ = user_secrets[:]
def __str__(self):
return str(self.__user_secrets__)
u1 = [ "홍길동", 23, "hong@test.com" ]
u2 = UserInfo()
u2.set_user_secrets(u1)
print(u1)
print(u2)
print("*" * 40)
u1[0] = "신길동"
print(u1)
print(u2)
print("*" * 40)
u3 = u2.get_user_secrets()
print(u2)
print(u3)
print("*" * 40)
u3[0] = "고길동"
print(u2)
print(u3)
💻 실행 결과
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['신길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['홍길동', 23, 'hong@test.com']
['홍길동', 23, 'hong@test.com']
****************************************
['홍길동', 23, 'hong@test.com'] # 인스턴스 내부의 값이 유지되는 것을 확인
['고길동', 23, 'hong@test.com']
의도된 사용에 반하는 방법으로 API를 사용하거나 보안에 취약한 API를 사용하여 발생할 수 있는 보안 약점
https://learn.microsoft.com/ko-kr/windows-server/administration/windows-commands/ipconfig
Displays all current TCP/IP network configuration values and refreshes Dynamic Host Configuration Protocol (DHCP) and Domain Name System (DNS) settings. Used without parameters, ipconfig displays Internet Protocol version 4 (IPv4) and IPv6 addresses, subnet mask, and default gateway for all adapters.
💡 어댑터(adapter)
NIC(Network Interface Controller or Card)
c:\Users\r2com> ipconfig
Windows IP 구성
이더넷 어댑터 이더넷:
미디어 상태 . . . . . . . . : 미디어 연결 끊김
연결별 DNS 접미사. . . . :
무선 LAN 어댑터 로컬 영역 연결* 9:
미디어 상태 . . . . . . . . : 미디어 연결 끊김
연결별 DNS 접미사. . . . :
무선 LAN 어댑터 로컬 영역 연결* 10:
미디어 상태 . . . . . . . . : 미디어 연결 끊김
연결별 DNS 접미사. . . . :
무선 LAN 어댑터 Wi-Fi:
연결별 DNS 접미사. . . . :
링크-로컬 IPv6 주소 . . . . : fe80::622c:5a77:1e68:babd%14
IPv4 주소 . . . . . . . . . : 192.168.0.143 (1)
서브넷 마스크 . . . . . . . : 255.255.255.0 (2)
기본 게이트웨이 . . . . . . : 192.168.0.1 (3)
▫ 인터넷 공간에서 각 호스트의 고유한 식별자를 의미
▫ 컴퓨터 네트워크에서 장치들이 서로를 인식하고 통신을 하기 위해서 사용하는 특수한 번호(주소)
▫ IPv4 주소를 표기할 때는 8비트 단위의 옥텟(octet)으로 나눠서 각 옥텟은 콤마(.)로 구분해서 표기
▫ 10진수로 표기 → 1옥텟은 0~255를 나타낼 수 있음
192 . 168 . 0 . 143
1100 0000 1010 1000 0000 0000 1000 1111
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ 옥텟
📝 네트워크 주소와 호스트 주소 구분
네트워크 주소
▫ 호스트를 모은 네트워크를 지칭하는 주소
▫ 네트워크 주소가 동일한 네트워크를 로컬 네트워크라고 함
호스트 주소
▫ 하나의 네트워크 내에 존재하는 호스트를 구분하기 위한 주소
📝 IP주소의 클래스
▪ Classful
📝 특수 목적으로 예약된 IPv4 주소
https://krnic.kisa.or.kr/jsp/resources/ipv4Info.jsp
특수 목적으로 예약된 것은 공인 IP 주소로 할당 받는 것이 불가능
IP 주소를 네트워크 ID와 호스트 ID로 구분하는 방법
▫ 서브넷 마스크 값을 조정해서 네크워크 영역을 조절
네트워크 ID → 많은 LAN 영역에서 자기 LAN 영역을 구분하기 위한 식별자
호스트 ID → 해당 LAN 영역에 속한 호스트 각각을 구분하기 위한 식별자
📝 CIDR(Classless Inter-Domain Routing)
▫ 클래스의 제한을 두지 않고 필요한 호스의 수에 따라 적당한 크기의 IP 주소를 할당하는 방법
▫ 다양한 길이의 전치부를 이용한 할당 방법
▫ L3 (네트워크) 계증의 장비
▫ 각기 다른 네트워크 ID를 사용하는 LAN 영역 사이를 연결해 주는 기능
▫ 게이트웨이는 소프트웨어적인 측면을 강조, 라우터는 하드웨어 측면을 강조
📝 라우팅(routing) vs 스위칭(switching)
라우팅
▫ 다른 네트워크 ID를 사용하는 LAN 영역 사이트를 연결해 주는 기능
▫ 인터넷 상의 트래픽 단위인 패킷(packet)을 효율적이고 효과적으로 최단거리 또는 최단시간에 전달할 수 있도록 하는 것
▫ 출발지부터 최종 목적지까지 논리적으로 주소가 부여된 패킷의 전달 과정
스위칭
▫ LAN 영역에서 MAC 주소에 기반해 내부 통신을 수행하는 과정
L1 (물리) 계층 - Repeater, Hub
L2 (데이터 링크) 계층 - Switch, Brdige
L3 (네트워크) 계층 - Router, L3 Switch
동일한 네트워크 ID를 공유하는 장치들의 집합
동일한 게이트웨이 주소를 사용하는 장치들의 집합
c:\Users\r2com> ipconfig/all
무선 LAN 어댑터 Wi-Fi:
연결별 DNS 접미사. . . . :
설명. . . . . . . . . . . . : Intel(R) Wi-Fi 6 AX201 160MHz
물리적 주소 . . . . . . . . : D0-3C-1F-1F-E7-3F (3) MAC
DHCP 사용 . . . . . . . . . : 예 (2)
자동 구성 사용. . . . . . . : 예
링크-로컬 IPv6 주소 . . . . : fe80::622c:5a77:1e68:babd%14(기본 설정)
IPv4 주소 . . . . . . . . . : 192.168.0.143(기본 설정)
서브넷 마스크 . . . . . . . : 255.255.255.0
임대 시작 날짜. . . . . . . : 2024년 3월 20일 수요일 17:36:41
임대 만료 날짜. . . . . . . : 2024년 3월 21일 목요일 17:24:52
기본 게이트웨이 . . . . . . : 192.168.0.1
DHCP 서버 . . . . . . . . . : 192.168.0.1
DHCPv6 IAID . . . . . . . . : 190344229
DHCPv6 클라이언트 DUID. . . : 00-01-00-01-2D-68-5B-BC-8C-B0-E9-1C-CD-36
DNS 서버. . . . . . . . . . : 192.168.0.1 (1)
Tcpip를 통한 NetBIOS. . . . : 사용
▫ 도메인 이름과 IP 주소의 대응 관계를 데이터베이스 형태로 저장하고 제공하는 서비스
▫ 호스트의 도메인 이름을 호스트의 네트워크 주소로 바꾸거나 그 반대의 변환을 수행할 수 있도록 하기 위해 개발
📝 도메인 주소 장점
▫ 하나의 IP 주소를 이용해 여러 개의 웹 서비스 운영이 가능
▫ 서비스 중인 IP 주소가 바뀌더라도 도메인 주소를 그대로 유지해 접속 방법 변경 없이 서비스를 유지할 수 있음
▫ 지리적으로 여러 위치에서 서비스 가능
📝 DNS 구조
▫ 역트리 구조로 최상위 루트부터 top-level 도메인, second-level 도메인, third-level 도메인과 같이 하위 레벨로 원하는 주소를 단계적으로 검색
▫ 각 계층의 경계는 "."으로 표시하고 뒤에서부터 앞으로 해석
▫ thrid.second.top. 과 같은 형태로 표현하고 맨 뒤의 루트(.)는 생략
📝 DNS 명명 규칙
▫ 도메인 계층은 최대 128계층까지 구성
▫ 계층 별 길이는 최대 63byte까지 사용할 수 있으며, 도메인 계층 구분자(".")를 포함해 전체 도메인 네임의 길이는 최대 255byte까지 사용
▫ 문자는 알파벳, 숫자, "-" 만 사용할 수 있으며 대소문자 구분 X
📝 루트 도메인
▫ 도메인을 구성하는 최상위 영역
▫ DNS 서버는 사용자가 쿼리한 도메인에 값을 직접 갖고 있거나 캐시에 저장된 정보를 이용해 응답
▫ DNS 서버에 해당 도메인의 정보가 없으면 루트 도메인을 관리하는 루트 DNS에 쿼리
▫ 루트 DNS는 전 세계에 13개가 있고 DNS 서버를 설치하면 루트 DNS의 IP 주소를 기록한 힌트(hint) 파일을 가지고 있어 루트 DNS 관련 정보를 별도로 설정할 필요 X
https://www.iana.org/domains/root/servers
📝 TLD(Top-Level Domain)
IANA(Internet Assigned Numbers Authority)에서 6가지 유형으로 구분
https://www.iana.org/domains/root/db
✔ generic (gTLD)
특별한 제한 없이 일반적으로 사용되는 최상위 도메인으로 세 글자 이상으로 구성
1980년대 7개의 gTLD로 시작
예) .com, .edu, .gov, .int, .mil, .net, .org
필요에 의해 새로운 gTLD가 지속적으로 만들어지고 있음
종류 | 뜻 |
---|---|
com | 일반 기업체 |
edu | 4년제 이상 교육 기관 |
gov | 미국 연방 정보 기관 |
int | 국제 기구·기관 |
mil | 미국 연방 군사 기관 |
net | 네트워크 관리 기관 |
org | 비영리기관 |
✔ country-code (ccTLD)
국가 최상위 도메인으로 ISO 3166 표준에 의해 규정된 두 글자의 국가 코드를 사용
→ https://www.iso.org/obp/ui/#search
일반적으로 ccTLD를 사용하는 경우, Second Level TLD에는 gTDL에서 구분한 것 처럼 사이트 용도에 따른 코드를 사용
예) co.kr, go.kr
우리나라는 gTLD를 두 글자로 줄여 사용하는데, 호주나 대만 등은 gTDL를 그대로 사용하는 나라도 있음
예) com.au, gov.au, com.tw, gov.tw 등
✔ sponsored (sTLD)
특정 목적을 위한 스폰서를 두고 있는 최상위 도메인
스폰서는 특정 민족공동체, 전문자 집단, 지리적 위치 등이 속할 수 있음
.aero, asia, .edu, .museum 등
✔ infrastructure
운용 상 중요한 인프라 식별자 공간을 지원하기 위해 전용으로 사용되는 최상위 도메인
.arpa
→ 인터넷 안정성을 유지하기 위해 새로운 모든 인프라 하위 도메인이 배칠될 도메인 공간 역할
✔ generic-restricted (grTLD)
특정 기준을 충족하는 사람이나 단체가 사용할 수 있는 최상위 도메인
.biz, .name, .pro
✔ test (tTLD)
IDN(Internationalized Domain Name) 개발 프로세스에서 테스트 목적으로 사용하는 최상위 도메인
.test
c:\Users\r2com> ipconfig /flushdns # DNS 캐시 테이블을 삭제
c:\Users\r2com> ipconfig /displaydns # DNS 캐시 테이블을 조회
Windows IP Configuration # DNS 캐시가 모두 지워지고 없는 상태
C:\Users\User> curl https://www.google.com # DNS 쿼리 결과를 캐시에 반영
C:\Users\User> ipconfig /displaydns
Windows IP Configuration
www.google.com → 도메인 주소에 대한 IP 정보가 출력되는 것을 확인 가능
----------------------------------------
Record Name . . . . . : www.google.com
Record Type . . . . . : 1
Time To Live . . . . : 3
Data Length . . . . . : 4
Section . . . . . . . : Answer
A (Host) Record . . . : 142.250.206.228
📝 DNS 동작 방식
재귀적 쿼리(Recursive Query) + 반복적 쿼리(Iterative Query)
▫ 재귀적 쿼리는 쿼리를 보낸 클라이언트에 서버가 최종 결과값을 반환하는 서버 중심 쿼리
▫ 반복적 쿼리는 최종값을 받을 때까지 클라이언트에서 쿼리를 계속 진행하는 방식
▫ 재귀적 쿼리는 클라이언트와 로컬 DNS 간에서 사용
▫ 반복적 쿼리는 로컬 DNS 서버와 상위 DNS 구간에서 사용
📝 DNS 영역 파일(zone file) 주요 레코드
종류 | 의미 | 뜻 |
---|---|---|
A | IPv4 호스트 | 도메인 주소를 IP 주소(IPv4)로 매핑 |
AAAA | IPv6 호스트 | 도메인 주소를 IP 주소(IPv6)로 매핑 |
CNAME | 별칭 | 도메인 주소에 대한 별칭 |
SOA | 권한 시작 | 본 영역 데이터에 대한 권한 |
NS | 도메인 네임 서버 | 본 영역에 대한 네임 서버 |
MX | 메일 교환기 | 도메인에 대한 메일 서버 정보 |
PTR | 포인터 | IP 주소를 도메인에 매핑(역방향) |
TXT | 레코드 | 도메인에 대한 일반 텍스트 |