'\', '\\', '<', '>', '$', '#', '!', '?', '*', '`', '&', ';', ' ', '\t'
등을 UI에서 입력했더니 의도하지 않은 동작이 일어나는 것은 이러한 유효성 검토가 충분히 않다는 것.
"; reboot && reboot || reboot\nreboot"
이라는 문자(또는 유사한 Shell injection 문자열)를 입력하였더니 재부팅이 된다면 심각한 보안 문제가 있다는 것.
ASCII | NUL '\0' |
^A (SOH) |
^B (STX) |
^C (ETX) |
^D (EOT) |
^E (ENQ) |
^F (ACK) |
^G (BEL) '\a' |
^H (BS) '\b' |
^L (HT) '\t' |
^J (LF) '\n' |
^K (VT) '\v' |
^L (FF) '\f' |
^M (CR) '\r' |
^N (SO) |
^O (SI) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DEC | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | O9 | 10 | 11 | 12 | 13 | 14 | 15 |
OCT | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
HEX | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0A | 0B | 0C | 0D | 0E | 0F |
ASCII | ^P (DLE) |
^Q (DC1) |
^R (DC2) |
^S (DC3) |
^T (DC4) |
^U (NAK) |
^V (SYN) |
^W (ETB) |
^X (CAN) |
^Y (EM) |
^Z (SUB) |
^[ (ESC) '\e' |
^\ (FS) |
^] (GS) |
^^ (RS) |
^_ (US) |
DEC | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
OCT | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
HEX | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D | 1E | 1F |
ASCII | SPACE | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
DEC | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
OCT | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
HEX | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 2A | 2B | 2C | 2D | 2E | 2F |
ASCII | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
DEC | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
OCT | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
HEX | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B | 3C | 3D | 3E | 3F |
ASCII | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
DEC | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
OCT | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
HEX | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 4A | 4B | 4C | 4D | 4E | 4F |
ASCII | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
DEC | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
OCT | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 |
HEX | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 5A | 5B | 5C | 5D | 5E | 5F |
ASCII | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
DEC | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
OCT | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 |
HEX | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 6A | 6B | 6C | 6D | 6E | 6F |
ASCII | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ^? (DEL) |
DEC | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
OCT | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 |
HEX | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 7A | 7B | 7C | 7D | 7E | 7F |
0123456789
abcdefABCDEF0123456789
HT (0x09, '\t') SP (0x20, ' ')
HT (0x09, '\t') LF (0x0a, '\n') VT (0x0b) FF (0x0c) CR (0x0d, '\r') SP (0x20, ' ')
!"#$%&'()*+,-./<=>?@{|}~
('\')
는 다음에 오는 문자를 그 자체로 표현하려할 때 사용. (단, local-part 가 quote ('"')
문자로 쌓여있는 않는 경우에 사용함)
Abc\@def@example.com
Fred\ Bloggs@example.com
Joe.\\Blow@example.com
"Abc@def"@example.com
"Fred Bloggs"@example.com
('"')
로 쌓여있지 않는 경우에는 기본적으로 알파벳, 숫자, 그리고 아래 명시한 특수 문자만 허용됩니다. (그 밖에는 quote ('"')
로 감싸거나 backslash ('\')
로 표현해야 합니다.)
! # $ % & ' * + - / = ? ^ _ ` . { | } ~
user+mailbox@example.com
customer/department=shipping@example.com
$A12345@example.com
!def!xyz%abc@example.com
_somename@example.com
("'")
와 acute accent ("`")
는 quote ('"')
와 같은 의미가 아님에 유의.
"jsmith@myvpn.example.com"
fe80:0000:0000:0000:0213:d4ff:fe47:14d5
fe80:0:0:0:213:d4ff:fe47:14d5
fe80:0000:0000:0000:0213:d4ff:fe47:14d5 => fe80::213:d4ff:fe47:14d5
0:0:0:0:0:0:0:1 => ::1
0:0:0:0:0:0:0:0 => ::
(IPv4 compatible 주소) 0:0:0:0:0:0:192.168.0.1 => ::192.168.0.1
(IPv4 mapped 주소) 0:0:0:0:0:ffff:192.168.0.2 => ::ffff:192.168.0.2
fe80::213:d4ff:fe47:14d5%eth0
<ip>/<prefix>
<ip>/<netmask>
<ip1>-<ip2> OR <ip1>~<ip2>
<SINGLE | CIDR | NETMASK | RANGE>,[...]
socket.inet_pton({socket.AF_INET or socket.AF_INET6}, {str})
>>> import struct >>> import socket >>> in6_addr = socket.inet_pton(socket.AF_INET6, u"1234:5678:abcd:ffff::9999") >>> in6_addr '\x124Vx\xab\xcd\xff\xff\x00\x00\x00\x00\x00\x00\x99\x99' >>> a6_16 = struct.unpack(u"HHHHHHHH", socket.inet_pton(socket.AF_INET6, u"1234:5678:abcd:ffff::9999")) >>> a6_16 (13330, 30806, 52651, 65535, 0, 0, 0, 39321) >>> "%x:%x:%x:%x:%x:%x:%x:%x"%(socket.ntohs(a6_16[0]),socket.ntohs(a6_16[1]),socket.ntohs(a6_16[2]),socket.ntohs(a6_16[3]),socket.ntohs(a6_16[4]),socket.ntohs(a6_16[5]),socket.ntohs(a6_16[6]),socket.ntohs(a6_16[7])) '1234:5678:abcd:ffff:0:0:0:9999' >>> a6_32 = struct.unpack(u"IIII", socket.inet_pton(socket.AF_INET6, u"1234:5678:abcd:ffff::9999")) >>> a6_32 (2018915346, 4294954411, 0, 2576941056) >>> in_addr = socket.inet_pton(socket.AF_INET, u"101.102.103.104") in_addr = socket.inet_pton(socket.AF_INET, u"101.102.103.104") >>> in_addr 'efgh' >>> a4_8 = struct.unpack(u"BBBB", socket.inet_pton(socket.AF_INET, u"101.102.103.104")) >>> a4_8 (101, 102, 103, 104) >>> a4_32 = struct.unpack(u"I", socket.inet_pton(socket.AF_INET, u"101.102.103.104")) >>> a4_32 (1751606885,) >>> "%08x"%socket.ntohl(a4_32[0]) '65666768'
socket.inet_ntop({socket.AF_INET or socket.AF_INET6}, {inX_addr})
>>> import socket >>> s_address_family = socket.AF_INET6 >>> s_max_prefix_length = 128 >>> s_prefix_length = 64 >>> >>> s_bytearray = list() >>> s_prefix_index = 0 >>> while s_prefix_index < s_max_prefix_length: ... s_this_value = 0 ... for s_bit_index in xrange(8): ... if s_prefix_index < s_prefix_length: ... s_this_value |= 1 << (7 - s_bit_index) ... s_prefix_index += 1 ... s_bytearray.append(s_this_value) ... >>> s_inX_addr = str(bytearray(s_bytearray)) >>> >>> str = socket.inet_ntop(s_address_family, s_inX_addr) >>> str 'ffff:ffff:ffff:ffff::'
>>> import socket >>> s_bytearray = list() >>> s_bytearray.append(101) >>> s_bytearray.append(102) >>> s_bytearray.append(103) >>> s_bytearray.append(104) >>> in_addr = str(bytearray(s_bytearray)) >>> in_addr 'efgh' >>> str = socket.inet_ntop(socket.AF_INET, in_addr) >>> str '101.102.103.104' >>> import struct >>> in_addr = struct.pack(u"I", socket.htonl(0x01020304)) >>> str = socket.inet_ntop(socket.AF_INET, in_addr) >>> str '1.2.3.4' >>> in6_addr = struct.pack(u"HHHHHHHH", socket.htons(0x1234), socket.htons(0x2345), socket.htons(0x6789), socket.htons(0x0ABC), 0, 0, 0, socket.htons(0x9999)) >>> str = socket.inet_ntop(socket.AF_INET6, in6_addr) >>> str '1234:2345:6789:abc::9999'
import socket # IP 주소의 경우 다른 문자열이 같은 주소인 경우가 있으므로 이에 대한 비교 수행시 간략형 주소로 변경하여 비교하도록 고려해야 함. # => s_address_family 가 socket.AF_UNSPEC 으로 호출되는 경우 s_value가 None이 아닌 이상 절대로 반환값은 None이 반환되지 않습니다. # 이 경우 s_value 가 IPv4/IPv6인 경우는 축약형(normalize)으로 반환되며 나머지의 경우는 그대로 반환됩니다. # => s_address_family 가 socket.AF_INET 으로 호출되는 경우 s_value가 IPv4주소가 아닌 경우는 None이 반환됩니다. # => s_address_family 가 socket.AF_INET6 으로 호출되는 경우 s_value가 IPv6주소가 아닌 경우는 None이 반환됩니다. def _normalize_address(self, s_value, s_default_value = None, s_address_family = socket.AF_UNSPEC): if s_value == None: return s_default_value s_normalize_address = None # s_value의 IPv4, IPv6, FQDN 을 자동으로 감지하여 적절히 normalize 합니다. (재귀 호출로 구현) if s_address_family == socket.AF_UNSPEC: for s_this_address_family in [socket.AF_INET, socket.AF_INET6, None]: s_normalize_address = _normalize_address(self, s_value, s_default_value, s_this_address_family) if s_normalize_address != None: break return s_normalize_address # IPv4 주소에 한하여 normalize 합니다. 그 외의 경우는 None을 반환합니다. if s_address_family == socket.AF_INET: try: # 표준 normalize s_inX_addr = socket.inet_pton(s_address_family, s_value) s_normalize_address = socket.inet_ntop(s_address_family, s_inX_addr) except: # IPv4 주소중에는 1.2.3.4 가 정상이지만 001.002.003.004 형태로 입력하는 경우도 있을 수는 있다. (여기서는 이를 1.2.3.4로 변환) s_ipv4_pieces = s_value.split('.') if len(s_ipv4_pieces) == 4: s_temp_string = '' for s_piece in s_ipv4_pieces: try: if int(s_piece) < 0 and int(s_piece) >= 256: break if s_temp_string: s_temp_string += '.' + str(int(s_piece)) else: s_temp_string += str(int(s_piece)) except: # 숫자가 아님 break else: s_normalize_address = s_temp_string return s_normalize_address # IPv6 주소에 한하여 normalize 합니다. 그 외의 경우는 None을 반환합니다. if s_address_family == socket.AF_INET6: try: # 표준 normalize s_inX_addr = socket.inet_pton(s_address_family, s_value) s_normalize_address = socket.inet_ntop(s_address_family, s_inX_addr) except: # TODO : IPv6 compat/mapping 주소에서 IPv4 부분의 001.002.003.004 같은 형식의 입력에 대한 고려는 여기서 필요 s_normalize_address = None return s_normalize_address # FQDN / Interface-name (이 경우 그냥 반환합니다. 대소문자 고려는 호출부에서 하도록 합니다) return s_value
Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign "=") to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean.[1] It is defined as a MIME content transfer encoding for use in e-mail. QP works by using the equals sign "=" as an escape character. It also limits line length to 76, as some software has limits on line length.