Ver3.0 ๐ก๏ธ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์ ์ ๊ฒ๊ณผ ์ทจ์ฝ์ ๋ถ์ ์ค๋ฌด ์๋ฒฝ ๊ฐ์ด๋

๐ก๏ธ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์ ์ ๊ฒ๊ณผ ์ทจ์ฝ์ ๋ถ์ ์ค๋ฌด ์๋ฒฝ ๊ฐ์ด๋
์๋ , ์น๊ตฌ! ๐ ์ค๋์ ๊ฐ๋ฐ์๋ผ๋ฉด ๋ฐ๋์ ์์์ผ ํ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์ ์ ๊ฒ๊ณผ ์ทจ์ฝ์ ๋ถ์์ ๋ํด ์ด์ผ๊ธฐํด๋ณผ๊น ํด. ์์ฆ ๋ด์ค ๋ณด๋ฉด ํดํน ์ฌ๊ณ ๊ฐ ์ ๋ง ๋ง์์? ๊ฐ์ธ์ ๋ณด ์ ์ถ, ๋์ฌ์จ์ด ๊ณต๊ฒฉ... ์ด๋ฐ ์ผ๋ค์ด ๋จ์ ์ผ ๊ฐ์ง ์์ง? ์ฌ์ค ์ด๋ฐ ๋ณด์ ์ฌ๊ณ ์ ์๋น์๊ฐ ์์ฉํ๋ก๊ทธ๋จ์ ์ทจ์ฝ์ ์์ ์์๋๋ค๋ ๊ฑฐ ์๊ณ ์์์ด?
ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ๋ ๊ฑด ์ง์ ์ง๋ ๊ฒ๊ณผ ๋น์ทํด. ์๋ฌด๋ฆฌ ๋ฉ์ง ๋์์ธ๊ณผ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ๊ฐ์ถฐ๋, ๋ฌธ๊ณผ ์ฐฝ๋ฌธ์ ์๋ฌผ์ ๊ฐ ์๋ค๋ฉด? ๐ ๐ ๋๋์ด ์ฝ๊ฒ ๋ค์ด์ฌ ์ ์๊ฒ ์ง. ์์ฉํ๋ก๊ทธ๋จ๋ ๋ง์ฐฌ๊ฐ์ง์ผ. ๊ธฐ๋ฅ์ ์๋ฒฝํด๋ ๋ณด์ ์ทจ์ฝ์ ์ด ์๋ค๋ฉด ํด์ปค๋ค์ ๋์ดํฐ๊ฐ ๋์ด๋ฒ๋ฆฌ๋ ๊ฑฐ์ง.
๐ฏ ์ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์์ด ์ค์ํ ๊น?
๋จผ์ ํ์ค์ ์ธ ์ด์ผ๊ธฐ๋ถํฐ ํด๋ณผ๊ฒ. 2023๋ ํ ํด ๋์ ์ ์ธ๊ณ์ ์ผ๋ก ๋ฐ์ํ ๋ณด์ ์ฌ๊ณ ์ ์ฝ 43%๊ฐ ์์ฉํ๋ก๊ทธ๋จ ์ทจ์ฝ์ ์ ํตํด ๋ฐ์ํ์ด. ์ด๊ฒ ๋ฌด์จ ์๋ฏธ๋๋ฉด, ๋คํธ์ํฌ ๋ฐฉํ๋ฒฝ์ด๋ ์๋ฒ ๋ณด์์ด ์๋ฌด๋ฆฌ ํผํผํด๋ ์์ฉํ๋ก๊ทธ๋จ ์์ฒด์ ๊ตฌ๋ฉ์ด ์์ผ๋ฉด ์์ฉ์๋ค๋ ๊ฑฐ์ง.
๊ฐ๋ฐ์๋ก์ ์ฐ๋ฆฌ๊ฐ ๋ง๋๋ ํ๋ก๊ทธ๋จ์ ๋จ์ํ ๊ธฐ๋ฅ๋ง ์ ์๋ํ๋ฉด ๋๋ ๊ฒ ์๋์ผ. ์ฌ์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ๋ณดํธํ๊ณ , ์์คํ ์ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๋ฉฐ, ์ ์์ ์ธ ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ฐฉ์ดํ ์ ์์ด์ผ ํด. ์ด๊ฒ ๋ฐ๋ก ์ฑ ์ ์๋ ๊ฐ๋ฐ์์ ์์ธ์ง.
๐ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์์ ํต์ฌ ๊ฐ๋
๋ณธ๊ฒฉ์ ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ ์ ์, ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์์์ ๊ผญ ์์์ผ ํ ํต์ฌ ๊ฐ๋ ๋ค์ ์ ๋ฆฌํด๋ณผ๊ฒ. ์ด ๊ฐ๋ ๋ค์ ์์ผ๋ก ๊ณ์ ๋์ฌ ๊ฑฐ๋๊น ์ ๊ธฐ์ตํด๋๋ฉด ์ข์! ๐
๐ก๏ธ CIA ํธ๋ผ์ด์ด๋ (๋ณด์์ 3๋ ์์น)
๋ณด์์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ด ๋๋ ์ธ ๊ฐ์ง ์์น์ด์ผ:
์ธ๊ฐ๋์ง ์์ ์ฌ์ฉ์๊ฐ ์ ๋ณด์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ํ๋ ๊ฒ. ์๋ฅผ ๋ค์ด, ๋ค๋ฅธ ์ฌ๋์ ๋น๋ฐ๋ฒํธ๋ ๊ฐ์ธ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ด์ผ ํด.
๋ฐ์ดํฐ๊ฐ ๋ฌด๋จ์ผ๋ก ๋ณ๊ฒฝ๋๊ฑฐ๋ ์์๋์ง ์๋๋ก ๋ณด์ฅํ๋ ๊ฒ. ์ก๊ธ ๊ธ์ก์ด ์ค๊ฐ์ ๋ฐ๋๋ฉด ์ ๋๊ฒ ์ง?
์ธ๊ฐ๋ ์ฌ์ฉ์๊ฐ ํ์ํ ๋ ์ธ์ ๋ ์ง ์์คํ ๊ณผ ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์์ด์ผ ํด. DDoS ๊ณต๊ฒฉ์ผ๋ก ์๋น์ค๊ฐ ๋ง๋น๋๋ฉด ๊ฐ์ฉ์ฑ์ด ์นจํด๋ ๊ฑฐ์ผ.
๐ญ ๊ณต๊ฒฉ์์ ๊ด์ ์์ ์๊ฐํ๊ธฐ
๋ณด์์ ์ ๋๋ก ์ดํดํ๋ ค๋ฉด ๊ณต๊ฒฉ์์ฒ๋ผ ์๊ฐํ ์ค ์์์ผ ํด. ์ด๊ฑธ "ํด์ปค์ ๋ง์ธ๋์ "์ด๋ผ๊ณ ํ๋๋ฐ, ๋ด๊ฐ ๋ง๋ ํ๋ก๊ทธ๋จ์ ์ด๋ป๊ฒ ๊ณต๊ฒฉํ ์ ์์์ง ์์ํด๋ณด๋ ๊ฑฐ์ง. ๐ค
๐ ์ฃผ์ ๋ณด์ ์ทจ์ฝ์ ์ ํ TOP 10
OWASP(Open Web Application Security Project)๋ผ๋ ๊ตญ์ ๋ณด์ ์ปค๋ฎค๋ํฐ์์ ๋งค๋ ๋ฐํํ๋ "OWASP Top 10"์ด๋ผ๋ ๊ฒ ์์ด. ๊ฐ์ฅ ์ํํ ์น ์ ํ๋ฆฌ์ผ์ด์ ๋ณด์ ์ทจ์ฝ์ 10๊ฐ์ง๋ฅผ ์ ๋ฆฌํ ๊ฑด๋ฐ, ์ด๊ฑด ๊ฐ๋ฐ์๋ผ๋ฉด ํ์๋ก ์์์ผ ํด! ๊ฐ๊ฐ์ ์์ธํ ์ดํด๋ณด์. ๐
1๏ธโฃ ์ธ์ ์ (Injection)
์ธ์ ์ ์ ๊ฐ์ฅ ์ํํ๊ณ ํํ ์ทจ์ฝ์ ์ค ํ๋์ผ. ๊ณต๊ฒฉ์๊ฐ ์ ๋ขฐํ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ช ๋ น์ด๋ ์ฟผ๋ฆฌ์ ์ผ๋ถ๋ก ์ ์กํด์, ์๋ํ์ง ์์ ๋ช ๋ น์ ์คํ์ํค๋ ๊ฑฐ์ง.
์ทจ์ฝํ ์ฝ๋๋ฅผ ๋ณผ๊น?
String query = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
์ด ์ฝ๋์ ๋ฌธ์ ์ ์ ๋ญ๊น? ์ฌ์ฉ์ ์
๋ ฅ๊ฐ์ ๊ทธ๋๋ก ์ฟผ๋ฆฌ์ ๋ฃ๊ณ ์์ด. ๋ง์ฝ ๊ณต๊ฒฉ์๊ฐ username์ ' OR '1'='1์ ์
๋ ฅํ๋ฉด?
์ด๋ ๊ฒ ๋๋ฉด์ ๋ชจ๋ ์ฌ์ฉ์ ์ ๋ณด๊ฐ ์กฐํ๋ผ๋ฒ๋ ค! ๐ฑ '1'='1'์ ํญ์ ์ฐธ์ด๋๊น.
Prepared Statement๋ฅผ ์ฌ์ฉํ๋ฉด ๋ผ:
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
โข LDAP Injection: LDAP ์ฟผ๋ฆฌ ์กฐ์
โข XPath Injection: XML ๋ฐ์ดํฐ ์กฐ์
โข NoSQL Injection: NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณต๊ฒฉ
2๏ธโฃ ์ทจ์ฝํ ์ธ์ฆ (Broken Authentication)
์ธ์ฆ๊ณผ ์ธ์ ๊ด๋ฆฌ๊ฐ ์ ๋๋ก ๊ตฌํ๋์ง ์์ผ๋ฉด, ๊ณต๊ฒฉ์๊ฐ ๋ค๋ฅธ ์ฌ์ฉ์์ ๊ณ์ ์ ํ์ทจํ ์ ์์ด. ์ด๊ฑด ์ ๋ง ์ฌ๊ฐํ ๋ฌธ์ ์ง! ๐
"123456", "password" ๊ฐ์ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ฉํ๋ฉด ์ ๋ผ. ์ต์ 8์ ์ด์, ๋์๋ฌธ์/์ซ์/ํน์๋ฌธ์ ์กฐํฉ์ ์๊ตฌํด์ผ ํด.
์ ์ถ๋ ๊ณ์ ์ ๋ณด๋ฅผ ๋๋์ผ๋ก ์๋ํ๋ ๊ณต๊ฒฉ. ๋ก๊ทธ์ธ ์๋ ํ์ ์ ํ๊ณผ CAPTCHA๋ก ๋ฐฉ์ดํ ์ ์์ด.
URL์ ์ธ์ ID๋ฅผ ํฌํจ์ํค๋ฉด ์ ๋ผ! ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ๋ Referer ํค๋๋ฅผ ํตํด ์ ์ถ๋ ์ ์๊ฑฐ๋ .
http://example.com/page?sessionid=abc123
// ์ข์ ์ โ
์ฟ ํค์ HttpOnly, Secure ํ๋๊ทธ์ ํจ๊ป ์ ์ฅ
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์ํ์ง ์๊ณ ์๋ฆฌ๋ฅผ ๋น์ ์ ๋๋ฅผ ๋๋นํด ์ผ์ ์๊ฐ ํ ์๋ ๋ก๊ทธ์์๋๋๋ก ํด์ผ ํด.
๋ค์ค ์ธ์ฆ(MFA)์ ๊ตฌํํ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๋น๋ฐ๋ฒํธ ์ธ์ SMS ์ธ์ฆ, OTP, ์์ฒด์ธ์ฆ ๋ฑ์ ์ถ๊ฐํ๋ฉด ๋ณด์์ด ํจ์ฌ ๊ฐํ๋ผ. ๐ฑ
3๏ธโฃ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ ๋ ธ์ถ (Sensitive Data Exposure)
๊ฐ์ธ์ ๋ณด, ์ ์ฉ์นด๋ ๋ฒํธ, ์๋ฃ ๊ธฐ๋ก ๊ฐ์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๊ฐ ์ ๋๋ก ๋ณดํธ๋์ง ์์ผ๋ฉด ํฐ์ผ ๋! ์ด๋ฐ ๋ฐ์ดํฐ๋ ์ ์ฅํ ๋๋, ์ ์กํ ๋๋ ์ํธํํด์ผ ํด. ๐
โข HTTPS ์ฌ์ฉ (TLS 1.2 ์ด์)
โข HTTP Strict Transport Security (HSTS) ํค๋ ์ค์
โข ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ GET ํ๋ผ๋ฏธํฐ๋ก ์ ์กํ์ง ์๊ธฐ
2. ์ ์ฅ ์ ์ํธํ (Encryption at Rest)
โข ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธํ
โข ๋น๋ฐ๋ฒํธ๋ ๋ฐ๋์ ํด์ ์ฒ๋ฆฌ (bcrypt, Argon2 ์ฌ์ฉ)
โข ์ํธํ ํค ๊ด๋ฆฌ ์์คํ ์ฌ์ฉ
3. ๋ถํ์ํ ๋ฐ์ดํฐ ์์ง ๊ธ์ง
โข ๊ผญ ํ์ํ ๋ฐ์ดํฐ๋ง ์์งํ๊ณ ์ ์ฅ
โข ์ฌ์ฉํ์ง ์๋ ๋ฐ์ดํฐ๋ ์์ ํ๊ฒ ์ญ์
String hashedPassword = MD5(password);
// bcrypt ์ฌ์ฉ โ
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(password);
// ๊ฒ์ฆ
boolean matches = encoder.matches(rawPassword, hashedPassword);
MD5๋ SHA-1 ๊ฐ์ ์ค๋๋ ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ ์์ ํ์ง ์์. bcrypt, scrypt, Argon2 ๊ฐ์ ๋๋ฆฐ ํด์ ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํด. ์ ๋๋ ค์ผ ํ๋๊ณ ? ๊ณต๊ฒฉ์๊ฐ ๋ฌด์ฐจ๋ณ ๋์ ๊ณต๊ฒฉ(brute force)์ ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ์ํด์์ผ! ๐
4๏ธโฃ XML ์ธ๋ถ ๊ฐ์ฒด (XXE - XML External Entities)
XML ํ์๊ฐ ์ธ๋ถ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ๋ฐ์ํ๋ ์ทจ์ฝ์ ์ด์ผ. ๊ณต๊ฒฉ์๊ฐ ์๋ฒ์ ํ์ผ์ ์ฝ๊ฑฐ๋, ๋ด๋ถ ์์คํ ์ ์ค์บํ๊ฑฐ๋, ์๋น์ค ๊ฑฐ๋ถ ๊ณต๊ฒฉ์ ํ ์ ์์ด.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
XML ํ์ ์ค์ ์์ ์ธ๋ถ ๊ฐ์ฒด ์ฒ๋ฆฌ๋ฅผ ๋นํ์ฑํํด์ผ ํด:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
5๏ธโฃ ์ทจ์ฝํ ์ ๊ทผ ํต์ (Broken Access Control)
์ฌ์ฉ์๊ฐ ์์ ์ ๊ถํ์ ๋์ด์๋ ์์ ์ ํ ์ ์๋ค๋ฉด? ๊ทธ๊ฑด ํฐ ๋ฌธ์ ์ผ! ์๋ฅผ ๋ค์ด, ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ด๋ฆฌ์ ๊ธฐ๋ฅ์ ์ ๊ทผํ๊ฑฐ๋, ๋ค๋ฅธ ์ฌ์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํ/์์ ํ ์ ์์ผ๋ฉด ์ ๋๊ฒ ์ง? ๐ซ
URL์ด๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ํด์ ๋ค๋ฅธ ์ฌ์ฉ์์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒ:
http://example.com/user/profile?id=123
โ id๋ฅผ 124๋ก ๋ฐ๊พธ๋ฉด ๋ค๋ฅธ ์ฌ๋ ํ๋กํ์ด ๋ณด์!
// ํด๊ฒฐ ๋ฐฉ๋ฒ โ
// ์๋ฒ์์ ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ํด๋น ๋ฆฌ์์ค์
// ์ ๊ทผ ๊ถํ์ด ์๋์ง ๋ฐ๋์ ํ์ธ
์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ด๋ฆฌ์ ๊ธฐ๋ฅ์ ์ ๊ทผ:
@PreAuthorize("hasRole('ADMIN')")
public String adminPage() {
// ๊ด๋ฆฌ์ ๊ธฐ๋ฅ
}
๊ฐ์ ๊ถํ ๋ ๋ฒจ์ ๋ค๋ฅธ ์ฌ์ฉ์ ๋ฐ์ดํฐ์ ์ ๊ทผ:
if (!document.getOwnerId().equals(currentUser.getId())) {
throw new AccessDeniedException("๊ถํ์ด ์์ต๋๋ค");
}
6๏ธโฃ ๋ณด์ ์ค์ ์ค๋ฅ (Security Misconfiguration)
๊ธฐ๋ณธ ์ค์ ์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฑฐ๋, ๋ถ์์ ํ ์ค์ , ๋ถํ์ํ ๊ธฐ๋ฅ ํ์ฑํ ๋ฑ์ด ์ด ๋ฒ์ฃผ์ ์ํด. ์์ธ๋ก ์ด๋ฐ ๋จ์ํ ์ค์๊ฐ ํฐ ๋ณด์ ์ฌ๊ณ ๋ก ์ด์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง์! ๐
โข ๋ถํ์ํ ์๋น์ค์ ํฌํธ ๋นํ์ฑํ
โข ์๋ฌ ๋ฉ์์ง์์ ๋ฏผ๊ฐํ ์ ๋ณด ์ ๊ฑฐ
โข ๋๋ ํ ๋ฆฌ ๋ฆฌ์คํ ๋นํ์ฑํ
โข ์ต์ ๋ณด์ ํจ์น ์ ์ฉ
โข ๊ฐ๋ฐ/๋๋ฒ๊ทธ ๋ชจ๋ ๋นํ์ฑํ (ํ๋ก๋์ ํ๊ฒฝ์์)
catch (Exception e) {
return "Error: " + e.getMessage() + "\nStack trace: " + e.getStackTrace();
}
// ๊ณต๊ฒฉ์์๊ฒ ์์คํ ๊ตฌ์กฐ ์ ๋ณด๋ฅผ ์ ๊ณต!
// ์ข์ ์ โ
catch (Exception e) {
logger.error("Error occurred", e); // ๋ก๊ทธ์๋ง ์์ธ ์ ๋ณด ๊ธฐ๋ก
return "์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํ์ธ์.";
}
7๏ธโฃ ํฌ๋ก์ค ์ฌ์ดํธ ์คํฌ๋ฆฝํ (XSS - Cross-Site Scripting)
XSS๋ ๊ณต๊ฒฉ์๊ฐ ์น ํ์ด์ง์ ์ ์์ ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์ ํด์, ๋ค๋ฅธ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋๊ฒ ํ๋ ๊ณต๊ฒฉ์ด์ผ. ์ด๋ฅผ ํตํด ์ฟ ํค๋ฅผ ํ์น๊ฑฐ๋, ์ธ์ ์ ํ์ทจํ๊ฑฐ๋, ์ฌ์ฉ์๋ฅผ ์์ผ ์ ์์ด. ๐ญ
์ฌ์ฉ์ ์ ๋ ฅ์ด ์ฆ์ ์๋ต์ ํฌํจ๋๋ ๊ฒฝ์ฐ:
String search = request.getParameter("q");
response.getWriter().write("๊ฒ์ ๊ฒฐ๊ณผ: " + search);
// ๊ณต๊ฒฉ URL
http://example.com/search?q=<script>alert(document.cookie)</script>
์ ์์ ์ธ ์คํฌ๋ฆฝํธ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋์ด, ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ๊ณ์ ์คํ๋๋ ๊ฒฝ์ฐ. ๊ฒ์ํ ๋๊ธ ๊ฐ์ ๊ณณ์์ ๋ง์ด ๋ฐ์ํด.
ํด๋ผ์ด์ธํธ ์ธก JavaScript์์ ๋ฐ์ํ๋ XSS:
document.getElementById("welcome").innerHTML =
"ํ์ํฉ๋๋ค, " + location.hash.substring(1);
1. ์ ๋ ฅ๊ฐ ๊ฒ์ฆ ๋ฐ ์ถ๋ ฅ ์ธ์ฝ๋ฉ
import org.apache.commons.text.StringEscapeUtils;
String safe = StringEscapeUtils.escapeHtml4(userInput);
// ๋๋ ํ ํ๋ฆฟ ์์ง ์ฌ์ฉ (์๋ ์ด์ค์ผ์ดํ)
// Thymeleaf, JSP์ c:out ๋ฑ
cookie.setHttpOnly(true); // JavaScript์์ ์ ๊ทผ ๋ถ๊ฐ
cookie.setSecure(true); // HTTPS์์๋ง ์ ์ก
8๏ธโฃ ์์ ํ์ง ์์ ์ญ์ง๋ ฌํ (Insecure Deserialization)
์ง๋ ฌํ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ขฐํ ์ ์๋ ์์ค์์ ๋ฐ์์ ์ญ์ง๋ ฌํํ๋ฉด, ์๊ฒฉ ์ฝ๋ ์คํ์ด๋ ๊ถํ ์์น ๊ฐ์ ์ฌ๊ฐํ ๊ณต๊ฒฉ์ ๋นํ ์ ์์ด. ๐ฐ
ObjectInputStream ois = new ObjectInputStream(untrustedInputStream);
Object obj = ois.readObject(); // ์ ์์ ์ธ ๊ฐ์ฒด๊ฐ ์คํ๋ ์ ์์!
// ์์ ํ ๋ฐฉ๋ฒ โ
// 1. ์ญ์ง๋ ฌํ ๋์ JSON ๊ฐ์ ๋ฐ์ดํฐ ํฌ๋งท ์ฌ์ฉ
// 2. ํ์ดํธ๋ฆฌ์คํธ ๊ธฐ๋ฐ ์ญ์ง๋ ฌํ ํํฐ ์ ์ฉ
// 3. ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ (HMAC ๋ฑ)
9๏ธโฃ ์๋ ค์ง ์ทจ์ฝ์ ์ด ์๋ ์ปดํฌ๋ํธ ์ฌ์ฉ
์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฑด ์ข์ง๋ง, ์ทจ์ฝ์ ์ด ์๋ ์ค๋๋ ๋ฒ์ ์ ์ฌ์ฉํ๋ฉด ์ํํด! ์ ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๊ณ ์ทจ์ฝ์ ์ ๋ชจ๋ํฐ๋งํด์ผ ํด. ๐ฆ
npm audit
# ์๋ ์์
npm audit fix
# Maven ํ๋ก์ ํธ
mvn dependency-check:check
๐ ๋ถ์ถฉ๋ถํ ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง
๊ณต๊ฒฉ์ด ๋ฐ์ํ์ ๋ ๊ฐ์งํ์ง ๋ชปํ๊ฑฐ๋, ์ฌํ ๋ถ์์ ํ ์ ์๋ค๋ฉด? ๊ทธ๊ฑด ์ ๋ง ๋ต๋ตํ ์ํฉ์ด์ผ. ์ ์ ํ ๋ก๊น ๊ณผ ๋ชจ๋ํฐ๋ง์ ๋ณด์์ ๋ง์ง๋ง ๋ฐฉ์ด์ ์ด๋ผ๊ณ ํ ์ ์์ด! ๐
โข ๊ถํ ๋ณ๊ฒฝ
โข ๋ฏผ๊ฐํ ๋ฐ์ดํฐ ์ ๊ทผ
โข ์ ๋ ฅ ๊ฒ์ฆ ์คํจ
โข ์ธ์ฆ/์ธ๊ฐ ์คํจ
โข ์๋ฒ ์ธก ์๋ฌ
โ ๏ธ ์ฃผ์์ฌํญ: ๋ก๊ทธ์ ๋น๋ฐ๋ฒํธ, ์ ์ฉ์นด๋ ๋ฒํธ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ฉด ์ ๋ผ!
๐ ๏ธ ๋ณด์ ์ ๊ฒ ์ค๋ฌด ํ๋ก์ธ์ค
์ด์ ์ค์ ๋ก ์์ฉํ๋ก๊ทธ๋จ์ ๋ณด์์ ์ ๊ฒํ๋ ํ๋ก์ธ์ค๋ฅผ ๋จ๊ณ๋ณ๋ก ์์๋ณด์. ์ด๊ฑด ๋ด๊ฐ ์ค๋ฌด์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๊ธฐ๋ ํด! ๐ผ
๐ 1๋จ๊ณ: ๊ณํ ์๋ฆฝ
๋ณด์ ์ ๊ฒ์ ์์ํ๊ธฐ ์ ์ ๋ช ํํ ๊ณํ์ด ํ์ํด. ๋ฌด์์ ์์ํ๋ฉด ์ค์ํ ๋ถ๋ถ์ ๋์น ์ ์๊ฑฐ๋ ! ๐ฏ
โข ์ด๋ค ์ ํ๋ฆฌ์ผ์ด์ /๋ชจ๋์ ์ ๊ฒํ ๊ฒ์ธ๊ฐ?
โข ์น, ๋ชจ๋ฐ์ผ, API ๋ฑ ์ด๋ค ํ๋ซํผ์ธ๊ฐ?
โข ๋ด๋ถ๋ง, ์ธ๋ถ๋ง ์ค ์ด๋๋ฅผ ์ ๊ฒํ ๊ฒ์ธ๊ฐ?
โข ์ปดํ๋ผ์ด์ธ์ค ์ค์ (ISMS-P, ISO 27001 ๋ฑ)
โข ํน์ ์ทจ์ฝ์ ๊ฒ์ฆ
โข ์ ๋ฐ์ ์ธ ๋ณด์ ์์ค ํ๊ฐ
โข ์ ๊ฒ ๊ธฐ๊ฐ: ๋ณดํต 1~4์ฃผ
โข ์ฐธ์ฌ ์ธ์: ๋ณด์ ์ ๋ฌธ๊ฐ, ๊ฐ๋ฐ์, ์์คํ ๊ด๋ฆฌ์
โข ํ์ํ ๋๊ตฌ ๋ฐ ํ๊ฒฝ
โข ์นจํฌ ํ ์คํธ ์น์ธ์ ํ๋ณด
โข ํ ์คํธ ๋ฒ์ ๋ฐ ๋ฐฉ๋ฒ์ ๋ํ ํฉ์
โข ๋ฐ์ดํฐ ๋ณดํธ ๋ฐ ๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ ๋ฐฉ์นจ ํ์ธ
๐ 2๋จ๊ณ: ์ ๋ณด ์์ง (Reconnaissance)
๊ณต๊ฒฉ์์ ๊ด์ ์์ ๋์ ์์คํ ์ ๋ํ ์ ๋ณด๋ฅผ ์์งํ๋ ๋จ๊ณ์ผ. ์ด ์ ๋ณด๋ค์ด ๋์ค์ ์ทจ์ฝ์ ์ ์ฐพ๋ ๋ฐ ํฐ ๋์์ด ๋ผ! ๐ต๏ธ
โข ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ๋ฐ ํ๋ ์์ํฌ
โข ์น ์๋ฒ (Apache, Nginx, IIS ๋ฑ)
โข ๋ฐ์ดํฐ๋ฒ ์ด์ค (MySQL, PostgreSQL, MongoDB ๋ฑ)
โข ์ฌ์ฉ ์ค์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ฒ์
2. ๋คํธ์ํฌ ์ ๋ณด
โข ๋๋ฉ์ธ ๋ฐ ์๋ธ๋๋ฉ์ธ
โข IP ์ฃผ์ ๋ฒ์
โข ์ด๋ฆฐ ํฌํธ ๋ฐ ์๋น์ค
3. ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์กฐ
โข URL ๊ตฌ์กฐ ๋ฐ ์๋ํฌ์ธํธ
โข ์ ๋ ฅ ํ๋ ๋ฐ ํ๋ผ๋ฏธํฐ
โข ํ์ผ ์ ๋ก๋ ๊ธฐ๋ฅ
โข API ๋ฌธ์
nmap -sV -sC target.com
# Sublist3r - ์๋ธ๋๋ฉ์ธ ์ฐพ๊ธฐ
python sublist3r.py -d target.com
# WhatWeb - ์น ๊ธฐ์ ํ์ง
whatweb target.com
# Wappalyzer - ๋ธ๋ผ์ฐ์ ํ์ฅ ํ๋ก๊ทธ๋จ์ผ๋ก ๊ธฐ์ ์คํ ํ์ธ
๐ฌ 3๋จ๊ณ: ์ทจ์ฝ์ ๋ถ์
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ทจ์ฝ์ ์ ์ฐพ์๋ณผ ์๊ฐ์ด์ผ! ํฌ๊ฒ ์ ์ ๋ถ์๊ณผ ๋์ ๋ถ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ด.
๐ ์ ์ ๋ถ์ (SAST - Static Application Security Testing)
์์ค ์ฝ๋๋ฅผ ์ง์ ๋ถ์ํด์ ์ทจ์ฝ์ ์ ์ฐพ๋ ๋ฐฉ๋ฒ์ด์ผ. ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ๋ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ด์ ๊ฐ๋ฐ ๋จ๊ณ์์ ์ ์ฉํด! ๐จโ๐ป
โข ๊ฐ๋ฐ ์ด๊ธฐ์ ์ทจ์ฝ์ ๋ฐ๊ฒฌ ๊ฐ๋ฅ
โข ์ ํํ ์์น ํ์ (ํ์ผ๋ช , ๋ผ์ธ ๋ฒํธ)
โข ์ ์ฒด ์ฝ๋๋ฒ ์ด์ค ๊ฒ์ฌ ๊ฐ๋ฅ
โข False Positive๊ฐ ์ ์
โข ๋ฐํ์ ์ทจ์ฝ์ ๋ฐ๊ฒฌ ์ด๋ ค์
โข ์ค์ ์ค๋ฅ ํ์ง ์ ํ์
โข ์ธ์ด๋ณ ๋๊ตฌ ํ์
SonarQube Checkmarx Fortify Veracode ESLint (JavaScript) Bandit (Python) FindBugs (Java)
mvn sonar:sonar \
-Dsonar.projectKey=my-project \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=your-token
๐ฎ ๋์ ๋ถ์ (DAST - Dynamic Application Security Testing)
์ค์ ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ฉด์ ์ธ๋ถ์์ ๊ณต๊ฒฉ์ ์๋ฎฌ๋ ์ด์ ํ๋ ๋ฐฉ๋ฒ์ด์ผ. ๋ธ๋๋ฐ์ค ํ ์คํธ๋ผ๊ณ ๋ ํด. ๐ญ
โข ์ค์ ๋ฐํ์ ํ๊ฒฝ์์ ํ ์คํธ
โข ์ค์ ์ค๋ฅ ๋ฐ ํ๊ฒฝ ๋ฌธ์ ๋ฐ๊ฒฌ
โข ์์ค ์ฝ๋ ์์ด๋ ํ ์คํธ ๊ฐ๋ฅ
โข ์ค์ ๊ณต๊ฒฉ ์๋๋ฆฌ์ค ์ฌํ
โข ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ์ ํ์
โข False Positive ๋ง์
โข ์ ํํ ์์น ํ์ ์ด๋ ค์
โข ํ ์คํธ ์๊ฐ ์ค๋ ๊ฑธ๋ฆผ
OWASP ZAP Burp Suite Acunetix Netsparker AppScan
โ๏ธ 4๋จ๊ณ: ์นจํฌ ํ ์คํธ (Penetration Testing)
์ด์ ์ง์ง ํด์ปค์ฒ๋ผ ์์คํ ์ ๊ณต๊ฒฉํด๋ณด๋ ๋จ๊ณ์ผ! ๋ฌผ๋ก ํ๊ฐ๋ฐ์ ๋ฒ์ ๋ด์์๋ง ํด์ผ ํด. ๐
โข ์ฝํ ๋น๋ฐ๋ฒํธ ์ ์ฑ ํ์ธ
โข ๋ฌด์ฐจ๋ณ ๋์ ๊ณต๊ฒฉ ์๋
โข ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ
โข ์ธ์ ํ์์์ ํ์ธ
โข Remember Me ๊ธฐ๋ฅ ๋ณด์ ๊ฒ์ฆ
โข SQL Injection ์๋
โข XSS ๊ณต๊ฒฉ ์๋
โข Command Injection
โข Path Traversal
โข File Upload ์ทจ์ฝ์
โข ์์ง์ ๊ถํ ์์น ์๋
โข ์ํ์ ๊ถํ ์์น ์๋
โข IDOR ์ทจ์ฝ์ ํ์ธ
โข API ์๋ํฌ์ธํธ ๋ฌด๋จ ์ ๊ทผ
โข ๊ฒฐ์ ํ๋ก์ธ์ค ์ฐํ
โข ์ฟ ํฐ/ํฌ์ธํธ ์ค๋ณต ์ฌ์ฉ
โข ์ฌ๊ณ ๊ด๋ฆฌ ๋ก์ง ์ค๋ฅ
โข ๊ฒฝ์ ์กฐ๊ฑด(Race Condition) ๊ณต๊ฒฉ
โข JavaScript ์ฝ๋ ๋ถ์
โข ๋ก์ปฌ ์คํ ๋ฆฌ์ง/์ธ์ ์คํ ๋ฆฌ์ง ํ์ธ
โข CORS ์ค์ ๊ฒ์ฆ
โข Clickjacking ์ทจ์ฝ์
http://target.com/product?id=1'
โ ์๋ฌ ๋ฉ์์ง ํ์ธ
# 2๋จ๊ณ: Union-based SQL Injection
http://target.com/product?id=1' UNION SELECT NULL,NULL,NULL--
โ ์ปฌ๋ผ ๊ฐ์ ํ์
# 3๋จ๊ณ: ๋ฐ์ดํฐ ์ถ์ถ
http://target.com/product?id=1' UNION SELECT username,password,email FROM users--
# 4๋จ๊ณ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ณด ์์ง
http://target.com/product?id=1' UNION SELECT table_name,NULL,NULL FROM information_schema.tables--
๋ฌผ๋ก ์ค์ ๋ก๋ ์ด๋ ๊ฒ ๊ฐ๋จํ์ง ์์! WAF(Web Application Firewall)๋ฅผ ์ฐํํ๊ฑฐ๋, ์ธ์ฝ๋ฉ์ ์ฌ์ฉํ๊ฑฐ๋, ์๊ฐ ๊ธฐ๋ฐ ๋ธ๋ผ์ธ๋ SQL Injection ๊ฐ์ ๊ณ ๊ธ ๊ธฐ๋ฒ์ด ํ์ํ ์๋ ์์ด. ๐
๐ 5๋จ๊ณ: ๋ณด๊ณ ์ ์์ฑ
๋ฐ๊ฒฌํ ์ทจ์ฝ์ ์ ์ ๋ฆฌํด์ ๋ณด๊ณ ์๋ฅผ ์์ฑํ๋ ๋จ๊ณ์ผ. ์ด๊ฒ ์๊ฐ๋ณด๋ค ์ค์ํด! ์๋ฌด๋ฆฌ ๋ง์ ์ทจ์ฝ์ ์ ์ฐพ์๋ ์ ๋๋ก ์ ๋ฌํ์ง ๋ชปํ๋ฉด ์์ฉ์๊ฑฐ๋ . ๐
โข ์ ์ฒด ๋ณด์ ์์ค ํ๊ฐ
โข ์ฃผ์ ๋ฐ๊ฒฌ ์ฌํญ
โข ์ํ๋ ํต๊ณ
โข ๊ถ์ฅ ์ฌํญ ์์ฝ
โ ๊ฒฝ์์ง์ด ์ฝ์ ๋ถ๋ถ์ด๋ ๊ธฐ์ ์ฉ์ด๋ ์ต์ํ!
โข ์ ๊ฒ ๋ฒ์ ๋ฐ ๊ธฐ๊ฐ
โข ์ฌ์ฉํ ๋ฐฉ๋ฒ๋ก ๋ฐ ๋๊ตฌ
โข ์ ์ธ ์ฌํญ
โข ํ ์คํธ ํ๊ฒฝ
๊ฐ ์ทจ์ฝ์ ๋ง๋ค ๋ค์ ์ ๋ณด ํฌํจ:
โข ์ ๋ชฉ: ๋ช ํํ๊ณ ๊ตฌ์ฒด์ ์ผ๋ก
โข ์ํ๋: Critical / High / Medium / Low
โข ์ค๋ช : ์ทจ์ฝ์ ์ด ๋ฌด์์ธ์ง
โข ์ํฅ: ์ ์ฉ ์ ์ด๋ค ํผํด๊ฐ ๋ฐ์ํ๋์ง
โข ์ฌํ ๋ฐฉ๋ฒ: ๋จ๊ณ๋ณ ์์ธ ์ค๋ช
โข ์ฆ๊ฑฐ: ์คํฌ๋ฆฐ์ท, ๋ก๊ทธ, ์ฝ๋ ์กฐ๊ฐ
โข ํด๊ฒฐ ๋ฐฉ์: ๊ตฌ์ฒด์ ์ธ ์์ ๋ฐฉ๋ฒ
โข ์ฐธ๊ณ ์๋ฃ: CVE, CWE, OWASP ๋งํฌ ๋ฑ
โข ์ฐ์ ์์๋ณ ์กฐ์น ๊ณํ
โข ์ฅ๊ธฐ์ ์ธ ๋ณด์ ๊ฐ์ ๋ฐฉํฅ
โข ๋ณด์ ๊ต์ก ํ์์ฑ
โข ์ ๊ธฐ ์ ๊ฒ ๊ณํ
โข ์ฌํ ๋ฐฉ๋ฒ์ ์์ธํ๋, ์ ์ฉ ๊ฐ๋ฅํ ์์ ํ ์ต์คํ๋ก์ ์ฝ๋๋ ์ ์ธ
โข ๊ฐ๊ด์ ์ด๊ณ ์ฌ์ค์ ๊ทผ๊ฑฐํ ๋ด์ฉ๋ง ์์ฑ
โข ๋ ์์ ๊ธฐ์ ์์ค์ ๋ง์ถฐ ์ค๋ช (๊ฒฝ์์ง์ฉ vs ๊ฐ๋ฐ์์ฉ)
๐ง 6๋จ๊ณ: ๊ฐ์ ์กฐ์น ๋ฐ ์ฌ๊ฒ์ฆ
์ทจ์ฝ์ ์ ๋ฐ๊ฒฌํ๋ ๊ฒ๋ ์ค์ํ์ง๋ง, ์ ๋๋ก ์์ ํ๋ ๊ฒ ๋ ์ค์ํด! ์์ ํ์๋ ๋ฐ๋์ ์ฌ๊ฒ์ฆ์ ํด์ผ ํด. ๐
โข Critical: ์ฆ์ ์กฐ์น (24์๊ฐ ์ด๋ด)
โข High: 1์ฃผ์ผ ์ด๋ด
โข Medium: 1๊ฐ์ ์ด๋ด
โข Low: ๋ค์ ๋ฆด๋ฆฌ์ค ์
2. ์์ ๋ฐฉ๋ฒ ๊ฒํ
โข ๊ฐ๋ฐํ๊ณผ ํ์
โข ์ฌ๋ฌ ํด๊ฒฐ ๋ฐฉ์ ๋น๊ต
โข ๋ถ์์ฉ ๊ฒํ
โข ํ ์คํธ ๊ณํ ์๋ฆฝ
3. ์์ ๊ตฌํ
โข ์ฝ๋ ์์
โข ๋จ์ ํ ์คํธ ์์ฑ
โข ์ฝ๋ ๋ฆฌ๋ทฐ
โข ํตํฉ ํ ์คํธ
4. ์ฌ๊ฒ์ฆ
โข ์ทจ์ฝ์ ์ด ์ค์ ๋ก ํด๊ฒฐ๋์๋์ง ํ์ธ
โข ์๋ก์ด ์ทจ์ฝ์ ์ด ์๊ธฐ์ง ์์๋์ง ํ์ธ
โข ๊ธฐ๋ฅ์ด ์ ์ ์๋ํ๋์ง ํ์ธ
๐จ ์ค์ ๋ณด์ ์ ๊ฒ ๋๊ตฌ ํ์ฉ๋ฒ
์ด๋ก ๋ ์ค์ํ์ง๋ง, ์ค์ ๋ก ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ์ค ์์์ผ ํด! ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ๋ณด์ ์ ๊ฒ ๋๊ตฌ๋ค์ ์์ธํ ์์๋ณด์. ๐ ๏ธ
๐ท๏ธ OWASP ZAP (Zed Attack Proxy)
๋ฌด๋ฃ ์คํ์์ค ์น ์ ํ๋ฆฌ์ผ์ด์ ๋ณด์ ์ค์บ๋์ผ. ์ด๋ณด์๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ผ๋ฉด์๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ ๊ณตํด! ๋ด๊ฐ ๊ฐ์ฅ ์ถ์ฒํ๋ ๋๊ตฌ ์ค ํ๋์ผ. ๐
์๋์ผ๋ก ์น์ฌ์ดํธ๋ฅผ ํฌ๋กค๋งํ๊ณ ์ทจ์ฝ์ ์ ์ค์บํด์ค.
zap-cli quick-scan --self-contained \
--start-options '-config api.disablekey=true' \
http://target.com
ํ๋ก์ ๋ชจ๋๋ก ๋ธ๋ผ์ฐ์ ํธ๋ํฝ์ ๊ฐ๋ก์ฑ์ ์๋์ผ๋ก ๋ถ์ํ ์ ์์ด. ์ด๊ฒ ์ง์ง ๊ฐ๋ ฅํด!
์ค์ ๋ก ๊ณต๊ฒฉ์ ์๋ํด์ ์ทจ์ฝ์ ์ ํ์ธํด. SQL Injection, XSS ๋ฑ ๋ค์ํ ๊ณต๊ฒฉ์ ์๋์ผ๋ก ์๋ํด์ค.
ํน์ ํ๋ผ๋ฏธํฐ์ ๋ค์ํ ๊ฐ์ ๋ฃ์ด๋ณด๋ฉด์ ์์์น ๋ชปํ ๋์์ ์ฐพ์๋ด.
์น์ฌ์ดํธ์ ๋ชจ๋ ํ์ด์ง์ ์๋ํฌ์ธํธ๋ฅผ ์๋์ผ๋ก ์ฐพ์์ค.
โข Context๋ฅผ ์ค์ ํด์ ๋ก๊ทธ์ธ์ด ํ์ํ ํ์ด์ง๋ ์ค์บ ๊ฐ๋ฅ
โข API ์ค์บ๋ ์ง์ํด (OpenAPI/Swagger ํ์ผ import)
โข CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉ ๊ฐ๋ฅ
๐ฅ Burp Suite
ํ๋ก ํด์ปค๋ค์ด ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋๊ตฌ์ผ. ์ ๋ฃ ๋ฒ์ (Pro)๊ณผ ๋ฌด๋ฃ ๋ฒ์ (Community)์ด ์๋๋ฐ, ๋ฌด๋ฃ ๋ฒ์ ๋ ์ถฉ๋ถํ ๊ฐ๋ ฅํด! ๐ฏ
๋ชจ๋ HTTP/HTTPS ํธ๋ํฝ์ ๊ฐ๋ก์ฑ์ ์์ ํ๊ณ ์ฌ์ ์กํ ์ ์์ด. ์ด๊ฒ Burp์ ํต์ฌ ๊ธฐ๋ฅ์ด์ง!
ํน์ ์์ฒญ์ ๋ฐ๋ณตํด์ ๋ณด๋ด๋ฉด์ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ํ ์ ์์ด. SQL Injection์ด๋ XSS ํ ์คํธํ ๋ ์ ๋ง ์ ์ฉํด!
์๋ํ๋ ๊ณต๊ฒฉ ๋๊ตฌ์ผ. ๋ค์ํ ํ์ด๋ก๋๋ฅผ ์๋์ผ๋ก ์๋ํด๋ณผ ์ ์์ด. (Pro ๋ฒ์ ์์๋ ์๋ ์ ํ ์์)
์๋ ์ทจ์ฝ์ ์ค์บ๋. ์ ํ๋๊ฐ ๋์์ False Positive๊ฐ ์ ์ด.
Base64, URL ์ธ์ฝ๋ฉ, HTML ์ํฐํฐ ๋ฑ ๋ค์ํ ์ธ์ฝ๋ฉ/๋์ฝ๋ฉ ์ง์.
๋ ๊ฐ์ ์์ฒญ/์๋ต์ ๋น๊ตํด์ ์ฐจ์ด์ ์ ์ฐพ์์ค. ๋ธ๋ผ์ธ๋ SQL Injection ์ฐพ์ ๋ ์ ์ฉํด!
1. Proxy์์ ๋ก๊ทธ์ธ ์์ฒญ์ ๊ฐ๋ก์ฑ
2. ์ฐํด๋ฆญ โ "Send to Repeater"
3. Repeater์์ username ํ๋ผ๋ฏธํฐ์
' OR '1'='1 ์
๋ ฅ4. "Send" ํด๋ฆญํด์ ์๋ต ํ์ธ
5. ์ทจ์ฝ์ ๋ฐ๊ฒฌ ์ "Send to Intruder"๋ก ๋ ๋ง์ ํ์ด๋ก๋ ํ ์คํธ
6. ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฆฌํด์ ๋ณด๊ณ ์์ ํฌํจ
๐ Nmap
๋คํธ์ํฌ ์ค์บ๋์ ์ ์ค์ ์ธ ๋๊ตฌ์ผ! ํฌํธ ์ค์บ, ์๋น์ค ํ์ง, OS ํ์ง ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํด. ๐
nmap target.com
# ์๋น์ค ๋ฒ์ ํ์ง
nmap -sV target.com
# OS ํ์ง
nmap -O target.com
# ์คํฌ๋ฆฝํธ ์ค์บ (์ทจ์ฝ์ ํ์ง)
nmap --script vuln target.com
# ์ ์ฒด ํฌํธ ์ค์บ
nmap -p- target.com
# ๋น ๋ฅธ ์ค์บ (์์ 100๊ฐ ํฌํธ)
nmap -F target.com
# ์คํ ์ค ์ค์บ (SYN ์ค์บ)
nmap -sS target.com
# UDP ์ค์บ
nmap -sU target.com
๐ Sqlmap
SQL Injection ๊ณต๊ฒฉ์ ์๋ํํด์ฃผ๋ ๋๊ตฌ์ผ. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ข ๋ฅ๋ฅผ ์๋์ผ๋ก ํ์งํ๊ณ , ์ต์ ์ ๊ณต๊ฒฉ ๋ฐฉ๋ฒ์ ์ฐพ์์ค! ๐ฏ
sqlmap -u "http://target.com/page?id=1"
# POST ๋ฐ์ดํฐ ํ ์คํธ
sqlmap -u "http://target.com/login" --data="username=admin&password=test"
# ์ฟ ํค ์ฌ์ฉ
sqlmap -u "http://target.com/page?id=1" --cookie="PHPSESSID=abc123"
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
sqlmap -u "http://target.com/page?id=1" --dbs
# ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ ๋ชฉ๋ก
sqlmap -u "http://target.com/page?id=1" -D database_name --tables
# ํ ์ด๋ธ ๋ฐ์ดํฐ ๋คํ
sqlmap -u "http://target.com/page?id=1" -D database_name -T users --dump
# OS ์ ํ๋ ์๋
sqlmap -u "http://target.com/page?id=1" --os-shell
--risk์ --level ์ต์
์ ์กฐ์ ํด์ ์์ ํ๊ฒ ํ
์คํธํด์ผ ํด!
๐๏ธ ๋ณด์ ์ฝ๋ฉ ์ค๋ฌด ๊ฐ์ด๋
์ทจ์ฝ์ ์ ์ฐพ๋ ๊ฒ๋ ์ค์ํ์ง๋ง, ์ ์ด์ ์์ ํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ๋ ์ค์ํ์ง! ์ค๋ฌด์์ ๋ฐ๋ก ์ ์ฉํ ์ ์๋ ๋ณด์ ์ฝ๋ฉ ๊ฐ์ด๋๋ฅผ ์๋ ค์ค๊ฒ. ๐ป
๐ก๏ธ ์ ๋ ฅ ๊ฒ์ฆ (Input Validation)
"๋ชจ๋ ์ ๋ ฅ์ ์ ์์ ์ด๋ผ๊ณ ๊ฐ์ ํ๋ผ" - ์ด๊ฒ ๋ณด์ ์ฝ๋ฉ์ ์ฒซ ๋ฒ์งธ ์์น์ด์ผ! ์ฌ์ฉ์ ์ ๋ ฅ, API ํ๋ผ๋ฏธํฐ, ํ์ผ ์ ๋ก๋ ๋ฑ ๋ชจ๋ ์ธ๋ถ ์ ๋ ฅ์ ์ฒ ์ ํ ๊ฒ์ฆํด์ผ ํด. โ
ํ์ฉํ ๊ฐ์ ๋ช ์ํ๋ ๊ฒ ์ฐจ๋จํ ๊ฐ์ ๋์ดํ๋ ๊ฒ๋ณด๋ค ์์ ํด!
if (input.contains("script") || input.contains("alert")) {
throw new ValidationException();
}
// ์ข์ ์ โ (ํ์ดํธ๋ฆฌ์คํธ)
if (!input.matches("^[a-zA-Z0-9_]{3,20}$")) {
throw new ValidationException("์ฌ์ฉ์๋ช ์ ์๋ฌธ, ์ซ์, ์ธ๋์ค์ฝ์ด๋ง ๊ฐ๋ฅํฉ๋๋ค");
}
@PostMapping("/user")
public ResponseEntity createUser(@Valid @RequestBody UserDto user) {
// @Valid ์ด๋ ธํ ์ด์ ์ด ์๋์ผ๋ก ๊ฒ์ฆ
}
public class UserDto {
@NotBlank(message = "์ด๋ฆ์ ํ์์ ๋๋ค")
@Size(min = 2, max = 50)
private String name;
@Email(message = "์ฌ๋ฐ๋ฅธ ์ด๋ฉ์ผ ํ์์ด ์๋๋๋ค")
private String email;
@Min(18)
@Max(120)
private int age;
}
DoS ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ๋ ฅ ๊ธธ์ด๋ฅผ ์ ํํด์ผ ํด.
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
String safe = StringEscapeUtils.escapeHtml4(userInput);
// SQL ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM users WHERE username = ?");
pstmt.setString(1, username);
๐ ์ธ์ฆ ๋ฐ ์ธ์ ๊ด๋ฆฌ
์์ ํ ์ธ์ฆ ์์คํ ์ ๊ตฌ์ถํ๋ ๊ฑด ์ ๋ง ์ค์ํด! ์ค๋ฌด์์ ์์ฃผ ์ฌ์ฉํ๋ ํจํด๋ค์ ์์๋ณด์. ๐
private static final int MIN_LENGTH = 8;
private static final String PASSWORD_PATTERN =
"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
public static boolean isValid(String password) {
if (password == null || password.length() < MIN_LENGTH) {
return false;
}
return password.matches(PASSWORD_PATTERN);
}
// ์ผ๋ฐ์ ์ธ ๋น๋ฐ๋ฒํธ ์ฒดํฌ
private static final Set<String> COMMON_PASSWORDS = Set.of(
"password", "123456", "qwerty", "admin"
);
public static boolean isCommon(String password) {
return COMMON_PASSWORDS.contains(password.toLowerCase());
}
}
public class LoginAttemptService {
private final int MAX_ATTEMPT = 5;
private LoadingCache<String, Integer> attemptsCache;
public LoginAttemptService() {
attemptsCache = CacheBuilder.newBuilder()
.expireAfterWrite(1, TimeUnit.DAYS)
.build(new CacheLoader<String, Integer>() {
public Integer load(String key) {
return 0;
}
});
}
public void loginFailed(String key) {
int attempts = attemptsCache.getUnchecked(key);
attempts++;
attemptsCache.put(key, attempts);
}
public boolean isBlocked(String key) {
return attemptsCache.getUnchecked(key) >= MAX_ATTEMPT;
}
}
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1) // ๋์ ์ธ์ ์ ํ
.maxSessionsPreventsLogin(true)
.and()
.sessionFixation().newSession() // ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ ๋ฐฉ์ด
.invalidSessionUrl("/login")
.and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
return http.build();
}
}
// ๋น๋ฐํค๋ ํ๊ฒฝ๋ณ์๋ ์ค์ ํ์ผ์์ ์ฝ์ด์ค๊ธฐ
private String SECRET_KEY = System.getenv("JWT_SECRET");
// ์งง์ ๋ง๋ฃ ์๊ฐ ์ค์ (15๋ถ)
private long EXPIRATION_TIME = 900000;
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// Refresh Token ๋ณ๋ ๊ด๋ฆฌ
public String generateRefreshToken(String username) {
return Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + 604800000)) // 7์ผ
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
๐ ์ํธํ ๋ฐ ํด์ฑ
๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ๋ณดํธํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์! ์ํธํ์ ํด์ฑ์ ๋ค๋ฅด๋ค๋ ๊ฒ๋ ๊ธฐ์ตํด์ผ ํด. ๐
โข ์๋ฐฉํฅ: ์ํธํ โ ๋ณตํธํ ๊ฐ๋ฅ
โข ํค๊ฐ ํ์
โข ์ฌ์ฉ ์: ํ์ผ ์ํธํ, ํต์ ์ํธํ
โข ์๊ณ ๋ฆฌ์ฆ: AES, RSA
ํด์ฑ (Hashing):
โข ๋จ๋ฐฉํฅ: ํด์ โ ์๋ณธ ๋ณต๊ตฌ ๋ถ๊ฐ
โข ํค ๋ถํ์ (Salt ์ฌ์ฉ)
โข ์ฌ์ฉ ์: ๋น๋ฐ๋ฒํธ ์ ์ฅ, ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ
โข ์๊ณ ๋ฆฌ์ฆ: bcrypt, Argon2, PBKDF2
@Service
public class PasswordService {
private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12); // strength
public String hashPassword(String plainPassword) {
return encoder.encode(plainPassword);
}
public boolean verifyPassword(String plainPassword, String hashedPassword) {
return encoder.matches(plainPassword, hashedPassword);
}
}
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESEncryption {
private static final String ALGORITHM = "AES";
private static final String KEY = System.getenv("ENCRYPTION_KEY"); // 32๋ฐ์ดํธ
public static String encrypt(String data) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encryptedData) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decrypted);
}
}
@Configuration
public class HttpsConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http.requiresChannel()
.anyRequest()
.requiresSecure();
return http.build();
}
}
// HSTS ํค๋ ์ถ๊ฐ
http.headers()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(31536000);
๐ก๏ธ API ๋ณด์
์์ฆ์ RESTful API๋ฅผ ๋ง์ด ์ฌ์ฉํ์์? API ๋ณด์๋ ์ ๋ง ์ค์ํด! ํนํ ๋ชจ๋ฐ์ผ ์ฑ์ด๋ SPA(Single Page Application)์์ API๋ฅผ ์ฌ์ฉํ ๋๋ ๋์ฑ ์ ๊ฒฝ ์จ์ผ ํด. ๐ฑ
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
@Component
public class RateLimitInterceptor implements HandlerInterceptor {
private final Map<String, Bucket> cache = new ConcurrentHashMap<>();
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String key = request.getRemoteAddr();
Bucket bucket = cache.computeIfAbsent(key, k -> createBucket());
if (bucket.tryConsume(1)) {
return true;
}
response.setStatus(429); // Too Many Requests
return false;
}
private Bucket createBucket() {
// ๋ถ๋น 100๊ฐ ์์ฒญ ํ์ฉ
Bandwidth limit = Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1)));
return Bucket.builder().addLimit(limit).build();
}
}
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://trusted-domain.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
};
}
}
@RestController
@RequestMapping("/api/v1/users")
public class UserControllerV1 {
// v1 API
}
@RestController
@RequestMapping("/api/v2/users")
public class UserControllerV2 {
// v2 API (๋ณด์ ๊ฐํ ๋ฒ์ )
}
private Long id;
private String username;
private String email;
@JsonIgnore // JSON ์๋ต์์ ์ ์ธ
private String password;
@JsonIgnore
private String ssn; // ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ
}
๐ ๋ณด์ ๊ต์ก๊ณผ ๋ฌธํ ๋ง๋ค๊ธฐ
์๋ฌด๋ฆฌ ์ข์ ๋ณด์ ๋๊ตฌ์ ํ๋ก์ธ์ค๊ฐ ์์ด๋, ํ์๋ค์ด ๋ณด์์ ์ค์์ฑ์ ์ดํดํ์ง ๋ชปํ๋ฉด ์์ฉ์์ด. ์กฐ์ง ๋ด์ ๋ณด์ ๋ฌธํ๋ฅผ ๋ง๋๋ ๊ฒ๋ ์ ๋ง ์ค์ํด! ๐ฅ
โข ๋ถ๊ธฐ๋ณ ๋ณด์ ์ํฌ์ต ๊ฐ์ต
โข ์ต์ ๋ณด์ ํธ๋ ๋ ๊ณต์
โข ์ค์ ์ฌ๋ก ๊ธฐ๋ฐ ํ์ต
โข ํดํน ์์ฐ ๋ฐ ๋ฐฉ์ด ์ค์ต
๊ฒ์์ฒ๋ผ ์ฌ๋ฏธ์๊ฒ ๋ณด์์ ๋ฐฐ์ธ ์ ์์ด! ํ ๋ด์์ CTF ๋ํ๋ฅผ ์ด์ด๋ณด๋ ๊ฒ๋ ์ข์.
์ถ์ฒ ํ๋ซํผ:
โข HackTheBox
โข TryHackMe
โข PicoCTF
โข OWASP WebGoat
โข ๋ณด์ ์ฒดํฌ๋ฆฌ์คํธ ์์ฑ
โข ์ทจ์ฝํ ์ฝ๋ ํจํด ๊ณต์
โข ์์ ํ ๋์ ์ ์
โข ์๋ํ ๋๊ตฌ ํ์ฉ (SonarQube ๋ฑ)
๊ฐ ํ์ ๋ณด์ ์ฑํผ์ธ์ ๋์ด์ ๋ณด์ ์ง์์ ์ ํํ๊ณ , ๋ณด์ ์ด์๋ฅผ ๋จผ์ ๋ฐ๊ฒฌํ๋๋ก ํด.
๐ ๋ณด์ ์ ๊ฒ ์๋ํ ๋ฐ CI/CD ํตํฉ
๋งค๋ฒ ์๋์ผ๋ก ๋ณด์ ์ ๊ฒ์ ํ๋ ๊ฑด ๋นํจ์จ์ ์ด์ผ. CI/CD ํ์ดํ๋ผ์ธ์ ๋ณด์ ์ ๊ฒ์ ํตํฉํด์ ์๋ํํ๋ฉด, ๊ฐ๋ฐ ์๋๋ฅผ ์ ์งํ๋ฉด์๋ ๋ณด์์ ๊ฐํํ ์ ์์ด! ์ด๊ฑธ DevSecOps๋ผ๊ณ ํด. ๐
stages:
- build
- test
- security
- deploy
sast:
stage: security
image: returntocorp/semgrep
script:
- semgrep --config=auto --json --output=semgrep-report.json .
artifacts:
reports:
sast: semgrep-report.json
allow_failure: false # ์ทจ์ฝ์ ๋ฐ๊ฒฌ ์ ๋น๋ ์คํจ
name: Security Scan
on: [push, pull_request]
jobs:
dependency-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
docker-scan:
stage: security
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- trivy image --severity HIGH,CRITICAL myapp:$CI_COMMIT_SHA
only:
- main
- develop
dast:
stage: security
image: owasp/zap2docker-stable
script:
- zap-baseline.py -t https://staging.example.com -r zap-report.html
artifacts:
paths:
- zap-report.html
only:
- staging
โข ์๋ํ: ๊ฐ๋ฅํ ๋ชจ๋ ๋ณด์ ๊ฒ์ฌ ์๋ํ
โข ๋น ๋ฅธ ํผ๋๋ฐฑ: ์ทจ์ฝ์ ๋ฐ๊ฒฌ ์ฆ์ ๊ฐ๋ฐ์์๊ฒ ์๋ฆผ
โข ์ง์์ ๊ฐ์ : ๋ณด์ ์ ์ฑ ๊ณผ ๋๊ตฌ ์ง์์ ์ ๋ฐ์ดํธ
โข ํ์ : ๊ฐ๋ฐ, ๋ณด์, ์ด์ ํ ๊ฐ ๊ธด๋ฐํ ํ๋ ฅ
๐ ํด๋ผ์ฐ๋ ํ๊ฒฝ ๋ณด์
์์ฆ์ AWS, Azure, GCP ๊ฐ์ ํด๋ผ์ฐ๋ ํ๊ฒฝ์ ๋ง์ด ์ฌ์ฉํ์์? ํด๋ผ์ฐ๋ ํ๊ฒฝ์์์ ๋ณด์๋ ์์์ผ ํด! โ๏ธ
โข ์ต์ ๊ถํ ์์น ์ ์ฉ
โข MFA(๋ค์ค ์ธ์ฆ) ํ์ ํ์ฑํ
โข ๋ฃจํธ ๊ณ์ ์ฌ์ฉ ๊ธ์ง
โข ์ ๊ธฐ์ ์ธ ๊ถํ ๊ฒํ
โข ์์ ์๊ฒฉ ์ฆ๋ช ์ฌ์ฉ (STS)
โข VPC(Virtual Private Cloud) ๊ตฌ์ฑ
โข ๋ณด์ ๊ทธ๋ฃน ๋ฐ NACL ์ค์
โข ํ๋ผ์ด๋น ์๋ธ๋ท ํ์ฉ
โข VPN ๋๋ Direct Connect ์ฌ์ฉ
โข DDoS ๋ฐฉ์ด (AWS Shield, CloudFlare ๋ฑ)
โข ์ ์ฅ ๋ฐ์ดํฐ ์ํธํ (EBS, S3 ๋ฑ)
โข ์ ์ก ๋ฐ์ดํฐ ์ํธํ (TLS/SSL)
โข KMS(Key Management Service) ํ์ฉ
โข ์ ๊ธฐ์ ์ธ ๋ฐฑ์
โข ๋ฒ์ ๊ด๋ฆฌ ํ์ฑํ
โข CloudTrail ํ์ฑํ (AWS)
โข CloudWatch ์๋ ์ค์
โข ๋ณด์ ์ด๋ฒคํธ ์ค์ ์ง์คํ
โข SIEM ๋๊ตฌ ํ์ฉ
โข ์ ๊ธฐ์ ์ธ ๋ก๊ทธ ๋ถ์
โข ๊ท์ ์ค์ ํ์ธ (GDPR, HIPAA ๋ฑ)
โข ์ ๊ธฐ์ ์ธ ๋ณด์ ๊ฐ์ฌ
โข ์ทจ์ฝ์ ์ค์บ
โข ์นจํฌ ํ ์คํธ (ํด๋ผ์ฐ๋ ์ ๊ณต์ ์ ์ฑ ํ์ธ)
aws ec2 describe-security-groups \
--filters Name=ip-permission.cidr,Values='0.0.0.0/0' \
--query 'SecurityGroups[*].[GroupName,GroupId]'
# S3 ๋ฒํท ํผ๋ธ๋ฆญ ์ก์ธ์ค ์ฐจ๋จ
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# CloudTrail ํ์ฑํ
aws cloudtrail create-trail \
--name my-trail \
--s3-bucket-name my-trail-bucket
aws cloudtrail start-logging --name my-trail
๐จ ๋ณด์ ์ฌ๊ณ ๋์ (Incident Response)
์๋ฌด๋ฆฌ ๋ณด์์ ์ํด๋ 100% ์๋ฒฝํ ์๋ ์์ด. ๋ณด์ ์ฌ๊ณ ๊ฐ ๋ฐ์ํ์ ๋ ์ด๋ป๊ฒ ๋์ํ๋๋๊ฐ ์ ๋ง ์ค์ํด! ๐
โข ์ฌ๊ณ ๋์ ํ ๊ตฌ์ฑ
โข ์ฐ๋ฝ๋ง ๊ตฌ์ถ
โข ๋์ ์ ์ฐจ ๋ฌธ์ํ
โข ์ ๊ธฐ์ ์ธ ํ๋ จ
โข ํ์ํ ๋๊ตฌ ์ค๋น
โข ์ด์ ์งํ ๋ชจ๋ํฐ๋ง
โข ๋ณด์ ์ด๋ฒคํธ ๋ถ์
โข ์ฌ๊ณ ์ฌ๊ฐ๋ ํ๊ฐ
โข ์ํฅ ๋ฒ์ ํ์
โข ์ฆ๊ฑฐ ์์ง ๋ฐ ๋ณด์กด
โข ๋จ๊ธฐ ๊ฒฉ๋ฆฌ: ์ฆ๊ฐ์ ์ธ ํผํด ์ฐจ๋จ
โข ์ฅ๊ธฐ ๊ฒฉ๋ฆฌ: ์์คํ ๋ณต๊ตฌ ์ค๋น
โข ๋ฐฑ์ ์์คํ ํ์ฑํ
โข ๋คํธ์ํฌ ์ธ๊ทธ๋จผํธ ๋ถ๋ฆฌ
โข ์ ์ฑ ์ฝ๋ ์ ๊ฑฐ
โข ์ทจ์ฝ์ ํจ์น
โข ์นจํด๋ ๊ณ์ ๋นํ์ฑํ
โข ์์คํ ์ฌ๊ตฌ์ถ
โข ์์คํ ์ ์ํ
โข ์๋น์ค ์ฌ๊ฐ
โข ๋ชจ๋ํฐ๋ง ๊ฐํ
โข ์ฌ๋ฐ ๋ฐฉ์ง ์กฐ์น
โข ์ฌ๊ณ ์์ธ ๋ถ์
โข ๋์ ๊ณผ์ ํ๊ฐ
โข ๊ฐ์ ์ฌํญ ๋์ถ
โข ๋ฌธ์ํ ๋ฐ ๊ณต์
โข ์ ์ฑ ๋ฐ ์ ์ฐจ ์ ๋ฐ์ดํธ
โข ์ฆ๊ฑฐ ๋ณด์กด: ๋ก๊ทธ, ๋ฉ๋ชจ๋ฆฌ ๋คํ ๋ฑ ์ญ์ ํ์ง ๋ง ๊ฒ
โข ์ํต: ๊ด๋ จ ๋ถ์ ๋ฐ ๊ฒฝ์์ง์ ์ฆ์ ๋ณด๊ณ
โข ๋ฒ์ ๊ณ ๋ ค: ํ์์ ๋ฒ ์งํ ๊ธฐ๊ด์ ์ ๊ณ
โข ๊ณ ๊ฐ ํต์ง: ๊ฐ์ธ์ ๋ณด ์ ์ถ ์ ๋ฒ์ ์๋ฌด ์ค์
๐ ๋ณด์ ํ์ต ๋ฆฌ์์ค ๋ฐ ์ปค๋ฎค๋ํฐ
๋ณด์์ ๊ณ์ ๊ณต๋ถํด์ผ ํ๋ ๋ถ์ผ์ผ. ์๋ก์ด ์ทจ์ฝ์ ๊ณผ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ด ๊ณ์ ๋์ค๊ฑฐ๋ ! ์ ์ฉํ ํ์ต ๋ฆฌ์์ค๋ค์ ์๊ฐํ ๊ฒ. ๐
Coursera Udemy Pluralsight ์ธํ๋ฐ ํจ์คํธ์บ ํผ์ค
์ค์ต ํ๋ซํผ:
HackTheBox TryHackMe PortSwigger Web Security Academy OWASP WebGoat PentesterLab
์๊ฒฉ์ฆ:
CEH (Certified Ethical Hacker) OSCP (Offensive Security Certified Professional) CISSP (Certified Information Systems Security Professional) CompTIA Security+
โข Krebs on Security: https://krebsonsecurity.com
โข The Hacker News: https://thehackernews.com
โข Schneier on Security: https://www.schneier.com
โข ๋ณด์๋ด์ค: https://www.boannews.com
โข KISA ์ธํฐ๋ท ๋ณดํธ๋๋ผ: https://www.boho.or.kr
๐ฏ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์, ์ ๋ง ๊ธด ์ฌ์ ์ด์์ง? ๐ ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์ ์ ๊ฒ๊ณผ ์ทจ์ฝ์ ๋ถ์์ ๋ํด ๋ง์ ๋ด์ฉ์ ๋ค๋ค์ด. ์ฒ์์๋ ๋ณต์กํ๊ณ ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์์ง๋ง, ํ๋์ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ์ตํ๊ฐ๋ค ๋ณด๋ฉด ์ด๋์ ๋ณด์ ์ ๋ฌธ๊ฐ๊ฐ ๋์ด ์์ ๊ฑฐ์ผ!
๊ฐ๋ฐ์๋ก์ ์ฐ๋ฆฌ๋ ์ฌ์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ ์ฑ ์์ด ์์ด. ๋ณด์์ ๋์ค์ผ๋ก ๋ฏธ๋ฃจ์ง ๋ง๊ณ , ๊ฐ๋ฐ ์ด๊ธฐ๋ถํฐ ๊ณ ๋ คํด์ผ ํด.
2. ๊ณต๊ฒฉ์์ ๊ด์ ์ผ๋ก ์๊ฐํ๊ธฐ
๋ด๊ฐ ๋ง๋ ์์คํ ์ ์ด๋ป๊ฒ ๊ณต๊ฒฉํ ์ ์์์ง ์์ํด๋ณด๋ ์ต๊ด์ ๋ค์ฌ. ์ด๊ฒ ์ทจ์ฝ์ ์ ์ฐพ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด์ผ.
3. ์ง์์ ์ธ ํ์ต
๋ณด์์ ๋์ด ์๋ ๋ถ์ผ์ผ. ์๋ก์ด ์ทจ์ฝ์ ๊ณผ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ด ๊ณ์ ๋์ค๋๊น, ๊พธ์คํ ๊ณต๋ถํ๊ณ ์ต์ ํธ๋ ๋๋ฅผ ๋ฐ๋ผ๊ฐ์ผ ํด.
4. ์๋ํ์ ํตํฉ
๋ณด์ ์ ๊ฒ์ CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉํด์ ์๋ํํ๋ฉด, ๊ฐ๋ฐ ์๋๋ฅผ ์ ์งํ๋ฉด์๋ ๋ณด์์ ๊ฐํํ ์ ์์ด.
5. ํ์ํฌ์ ๋ฌธํ
๋ณด์์ ํผ์ ํ๋ ๊ฒ ์๋์ผ. ํ ์ ์ฒด๊ฐ ๋ณด์์ ์ค์์ฑ์ ์ดํดํ๊ณ ํ๋ ฅํด์ผ ํจ๊ณผ์ ์ด์ผ.
๋ณด์์ ํ ๋ฒ ์ค์ ํ๊ณ ๋๋๋ ๊ฒ ์๋๋ผ, ์ง์์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ๊ฐ์ ํด์ผ ํ๋ ํ๋ก์ธ์ค์ผ. ์๋ฒฝํ ๋ณด์์ ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ํ ์ ์๋ ์ต์ ์ ๋คํด์ผ ํด. ๐ก๏ธ
์ด ๊ธ์ด ์์ฉํ๋ก๊ทธ๋๋ฐ ๋ณด์ ์ ๊ฒ๊ณผ ์ทจ์ฝ์ ๋ถ์์ ์์ํ๋ ๋ฐ ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ด. ๊ถ๊ธํ ์ ์ด ์๊ฑฐ๋ ๋ ๊น์ด ์๋ ๋ด์ฉ์ ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด, ๋ณด์ ์ปค๋ฎค๋ํฐ์ ์ฐธ์ฌํ๊ฑฐ๋ ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๐ช
์, ์ด์ ๋น์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ํ๊ฒ ๋ง๋ค์ด๋ณด์! ํ์ดํ ! ๐
๐ ๋ณด์์ ๋ชจ๋์ ์ฑ ์์ ๋๋ค!
์์ ํ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ์ฌ์ฉ์๋ฅผ ๋ณดํธํ๋ฉฐ,
๋ ๋์ ์ธํฐ๋ท ์ธ์์ ๋ง๋ค์ด๊ฐ์! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.