보안에서 공격 벡터는 흔히 이용자가 값을 자유롭게 입력할 수 있는 지점에서 발생
-> 취약점 발생을 줄이려면 이용자의 입력 값을 절대 신뢰해서는 안 되며, 항상 검증하여(Never Trust, Always Verify) 서버에서 올바른 데이터만 다루도록 강제해야 한다.
이때, 정규 표현식은 입력 값 검증에 활용되며, 잘못된 정규 표현식으로 잘못 검증 시 올바르지 않은 데이터가 서버에 넘어와 취약점으로 이어짐.
정규 표현식 = 특정한 패턴으로 문자열을 표현하는 식 -> 일반적으로 공격 벡터는 흔히 이용자가 값을 자유롭게 입력할 수 있는 지점에서 발생
-> 취약점 발생을 줄이려면 이용자의 입력 값을 절대 신뢰해서는 안 되며, 항상 검증하여(Never Trust, Always Verify) 서버에서 올바른 데이터만 다루도록 강제해야 한다.
이때, 정규 표현식은 입력 값 검증에 활용되며, 잘못된 정규 표현식으로 잘못 검증 시 올바르지 않은 데이터가 서버에 넘어와 취약점으로 이어짐.
정규 표현식 = 특정한 패턴으로 문자열을 표현하는 식 -> 일반적으로 문자열 내에서 원하는 패턴(어떤 문자 조합을 식으로 나타낸 것)의 문자열을 찾거나 치환할 때 사용
이메일 정규 표현식 예시: ^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$
- 정규 표현식에 매치: xxx@xxx.xxx
- 매치X: xxx@xxx.x
정규 표현식은 주로 로직 수행 전에 이용자가 입력한 값을 검증하기 위해 사용하므로, 위와 같은 이메일 정규 표현식의 경우 이용자가 알맞은 형식의 이메일을 입력했는지 검증 가능. 이메일 이외에 전화번호, 주민등록번호, 웹사이트 주소 등 입력 값이 특정 형식이어야 하는 모든 경우에 유용.
(ME: 악성 URL 등이 포함된 스팸 문자 탐지 등에 유용한 개념일 듯)
또, 매우 긴 문자열에서 원하는 형식의 문자열을 검색해 추출 시에도 사용.
- 정규 표현식은 '패턴' 또는 /패턴/의 형태로 작성되며, /로 패턴을 감싸는 경우에는 / 뒤에 플래그 작성 가능.
패턴 | 설명 |
문자 혹은 문자열 | 해당 문자/문자열과 매치 |
. | 모든 문자와 매치 |
| | 앞 또는 뒤 패턴과 매치 |
[ ] | [ ] 안의 문자와 매치 |
[^ ] | ^ 뒤의 패턴 제외한 나머지와 매치 |
^ | 어떤 문자열 시작이 특정 패턴인 경우 매치 |
$ | 어떤 문자열 끝이 특정 패턴인 경우 매치 |
\ | \ 뒤의 특수 문자와 매치 (특별 목적으로 사용되는 특수 문자를 문자 그대로 쓰기 위한 것) |
[A-Z] or [a-z] or [0-9] | 두 문자 사이 범위의 문자와 매치 |
\w | 알파벳 or 숫자 or _와 매치 |
\d | 숫자와 매치 |
\s | 공백 문자와 매치 |
패턴(수량자) | 설명 |
* | 앞에 나온 문자가 0개 이상이면 매치 |
+ | 앞에 나온 문자가 1개 이상이면 매치 |
? | 앞에 나온 문자가 0개 혹은 1개면 매치 |
수량자? | 수량자 뒤에 ? 붙이면 게으른 수량자 -> 최소한의 문자만 매치 |
{n} | 앞에 나온 문자가 정확히 n개이면 매치 |
{n, } | 앞에 나온 문자가 n개 이상이면 매치 |
{n1, n2} | 앞에 나온 문자가 n1개 이상, n2개 이하이면 매치 |
( ) | ()로 감싼 부분을 그룹화해 하나의 문자처럼 여김 |
기본적으로 정규 표현식의 수량자 = 탐욕적(greedy) 수량자 -> 가능한 많은 문자 매치 = 더 이상 매치하지 않을 때까지 모두 매치
과도한 매치 방지 => 게으른(lazy) 수량자 (수량자?)
*정규 표현식 플래그: 검색 옵션 지정 -> 일반적으로 " /패턴/플래그 " 형식
플래그 | 설명 |
g (global) | 매치하는 모든 문자/문자열 검색 |
i (ignore) | 대소문자 구분x 검색 |
m (multiline) | 여러 줄에서 검색 |
s (single line) | 메타문자 .가 개행문자도 포함 |
<python 정규 표현식>
- re 모듈 사용해 정규 표현식 사용
1. re.compile(pattern, flags): 정규 표현식 패턴 컴파일 - 패턴 객체 반환
2. re.search(pattern, string, flags): 문자열 내에서 패턴에 처음으로 매치하는 문자열 검색
- 매치 시 문자열 객체 반환, 없으면 None 반환. 문자열 객체의 group() 메서드 사용해 객체에서 문자열만 반환 가능.
3. re.match(pattern, string, flags): 문자열 시작 부분에서 패턴에 매치하는 문자열 검색
- re.search와 같음
4. re.fullmatch(pattern, string, flags): 전체 문자열이 패턴과 정확히 매치하는지 확인
- re.search와 같음
5. re.findall(pattern, string, flags): 문자열 내에서 패턴에 매치하는 모든 문자열 검색
- 모든 문자열을 리스트 형식으로 변환, 각 문자열은 리스트의 인덱스로 접근
6. re.finditer(pattern, string, flags): re.findall과 같음 - 모든 문자열 객체를 리스트 형식으로 반환
- flags: 함수의 flas 인자 값으로 지정 or 패턴에 인라인 형식으로 작성
이 때, 인라인 플래그는 정규 표현식 전체에 적용되지만, 특정 부분에만 적용되도록 제한 가능. 플래그를 그룹으로 묶어 특정 부분에만 적용 가능. -> ex) "(?i:hello) world"는 hello 부분에만 대소문자 구분 x
플래그 | flags 인자 값 | 인라인 플래그 |
i | re.I(re.IGNORECASE) | (?i) |
m | re.M(re.MULTILINE) | (?m) |
s | re.S(re.DOTALL) | (?s) |
g | 자동 적용 |
- Raw String(r-string)
: python에는 특수한 의미의 이스케이프 문자 존재. 이는 \ 뒤에 문자를 붙여 나타냄 -> ex) \t, \n
정규 표현식 패턴 내에 \ 사용 시, 이스케이프 문자로 인식해 의도와 다르게 해석될 수 있어 raw string 사용.
raw string은 문자열 앞에 r을 붙여 나타냄. ex) r"hello"
<JavaScript 정규표현식>
1. 정규 표현식 리터럴 사용: /패턴/ or /패턴/플래그/ 형태로 작성
2. RegExp 객체 생성: new RegExp(정규 표현식 리터럴, '플래그') or new RegExp('패턴', '플래그')로 객체 생성
함수 | 설명 |
pattern.exec(string) | 패턴에 처음 매치하는 문자열의 일치 정보 나타내는 결과 배열 반환 |
pattern.test(string) | 매치하는 부분 있으면 true, 없으면 false 반환 |
string.match(pattern) | 패턴에 매치하는 모든 문자열을 배열 형태로 반환 |
'CTF > Dreamhack' 카테고리의 다른 글
Markdown 문법 (0) | 2024.11.11 |
---|---|
Docker(도커) (4) | 2024.11.10 |