๋ท๋ผ ๋ณด์
๐ฑ Netra ๋ณด์ ๊ตฌ์ถ: ํ์ด์ฌ ๊ธฐ๋ฐ ์ ์ ์ ํ๋ฆฌ์ผ์ด์ ๋ณด์ ํ ์คํธ(SAST) ๋๊ตฌ ๋ง๋ค๊ธฐ
์ ๋ ์ฌ์ด๋ฒ๋ณด์ ํ์์ผ๋ก์ SonarQube, Semgrep ๋ฐ ๊ธฐํ ์ ์ ์ ํ๋ฆฌ์ผ์ด์
๋ณด์ ํ
์คํธ(SAST) ํ๋ซํผ์ด ์ํํธ์จ์ด๊ฐ ํ๋ก๋์
์ ๋๋ฌํ๊ธฐ ์ ์ ์ทจ์ฝ์ ์ ์ด๋ป๊ฒ ์๋ณํ๋์ง์ ๋ํด ํญ์ ํธ๊ธฐ์ฌ์ ๊ฐ์ ธ์์ต๋๋ค.
์ด ๋๊ตฌ๋ค์ ๋จ์ํ ์ฌ์ฉํ๋ ๊ฒ์ ๊ทธ์น์ง ์๊ณ ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ์๋ํ๋์ง ์ดํดํ๊ณ ์ ํ์ต๋๋ค. ์ด ํธ๊ธฐ์ฌ์ด Netra Security๋ผ๋ ๊ฒฝ๋ SAST ํ๋ซํผ์ ํ์ด์ฌ์ผ๋ก ๊ตฌํํ๊ฒ ๋ง๋ค์์ต๋๋ค.
์ด ๊ธ์์๋ ํ๋ก์ ํธ์ ๋๊ธฐ, ์๋ ๋ฐฉ์, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ๊ตฌ์ถํ๋ฉด์ ๋ฐฐ์ด ์ ์ ๊ณต์ ํ๊ฒ ์ต๋๋ค.
What is Netra Security?
Netra ๋ณด์์ ๋ฌด์์ธ๊ฐ์?
Netra Security๋ ์์ค ์ฝ๋์์ ์ง์ ์ผ๋ฐ์ ์ธ ๋ณด์ ์ทจ์ฝ์ ์ ์๋ณํ๋๋ก ์ค๊ณ๋ ํ์ด์ฌ ๊ธฐ๋ฐ ์ ์ ์ฝ๋ ๋ถ์ ๋๊ตฌ์
๋๋ค.
๋ค๋ผ(Netra)๋ผ๋ ์ด๋ฆ์ โ์ 3์ ๋โ์ด๋ผ๋ ๊ฐ๋ ์์ ์๊ฐ์ ๋ฐ์์ผ๋ฉฐ, ์ด๋ ์ทจ์ฝ์ ์ด ์ ์ฉ๋๊ธฐ ์ ์ ์จ๊ฒจ์ง ๋ณด์ ๋ฌธ์ ๋ฅผ ํ์งํ ์ ์๋ ๋ฅ๋ ฅ์ ์๋ฏธํฉ๋๋ค.
์ด ํ๋ก์ ํธ์ ๋ชฉํ๋ ์ํฐํ๋ผ์ด์ฆ ๋ณด์ ์ค์บ๋๋ฅผ ๋์ฒดํ๋ ๊ฒ์ด ์๋๋ผ ๋ค์๊ณผ ๊ฐ์ fondamentals์ ํ์ตํ๋ ๊ฒ์ด์์ต๋๋ค:
- ์ ์ ์ฝ๋ ๋ถ์
- ๋ณด์ ์ฝ๋ฉ ์ค์ฒ
- ์ทจ์ฝ์ ํ์ง
- ์ถ์ ๊ตฌ๋ฌธ ํธ๋ฆฌ(AST) ๋ถ์
- ๋ณด์ ๋๊ตฌ ๊ฐ๋ฐ
๋ฌธ์ ์
๋ง์ ๋ณด์ ์ทจ์ฝ์ ์ด ๊ฐ๋ฐ ๊ณผ์ ์์ ๋์ ๋ฉ๋๋ค.
os.system(user_input)
eval(user_input)
exec(user_input)
pickle.loads(user_data)
subprocess.run(user_input, shell=True)
These patterns can lead to:
- ๋ช ๋ น์ด ์ฃผ์
- ์ฝ๋ ์ฃผ์
- ์์ ์ฝ๋ ์คํ
- ์ํํ ์ง๋ ฌํ
Netra Security์ ์์ด๋์ด๋ ๊ฐ๋จํฉ๋๋ค: ์ทจ์ฝ์ ๋ฐ์ ์ด์ ์ ๋ถ์์ ํ ์ฝ๋ฉ ํจํด์ ํ์งํ๋ ๊ฒ์ ๋๋ค.
๋ฒ์ 1: ๊ท์น ๊ธฐ๋ฐ ๊ฐ์ง
Netra Security์ ์ฒซ ๋ฒ์งธ ๋ฒ์ ์ ๋ฌธ์์ด ๋งค์นญ๊ณผ ์ ๊ท์์ ์ฌ์ฉํ์ต๋๋ค.
{
"id": "NETRA-001",
"pattern": "os.system(",
"issue": "Command Injection",
"severity": "CRITICAL"
}
์ค์บ๋๋ ์์ค ์ฝ๋๋ฅผ ์ค ๋จ์๋ก ์ฝ์ผ๋ฉฐ ์ํํ ํจํด์ด ๋ํ๋๋์ง ํ์ธํฉ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ ๊ตฌํํ๊ธฐ ์ฌ์ ๊ณ ๊ธฐ๋ณธ์ ์ธ ํ์ง์ ์๋นํ ์ ์๋ํ์ต๋๋ค.
False Positives
์๋ฅผ ๋ค์ด:
message = "Never use eval() in production"
๊ฐ๋จํ ๋ฌธ์์ด ์ค์บ๋๋ ์ด ํ ์คํธ๊ฐ ์ค์ ์ทจ์ฝ์ ์ด ์๋๋ผ๋ ์ ์ ์๋ชป ์ธ์ํ์ฌ ์คํ์ง๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค.
Introducing AST Analysis
ํ์ด์ฌ์ ๋ด์ฅ ๋ชจ๋์ธ ast(์ถ์ ๊ตฌ๋ฌธ ํธ๋ฆฌ)๋ฅผ ์ ๊ณตํฉ๋๋ค.
AST๋ ์์ค ์ฝ๋๋ฅผ ์ค์ ํ๋ก๊ทธ๋จ์ ๋ก์ง์ ๋ํ๋ด๋ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋ณํํฉ๋๋ค.
for node in ast.walk(tree):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Attribute):
if node.func.attr == "system":
print("๋ช
๋ น์ด ์ฃผ์
์ํ")
์ด ๋ฐฉ์์ ์คํ์ง๋ฅผ ํฌ๊ฒ ์ค์ด๊ณ ๋ณด๋ค ์ ๋ขฐํ ๋งํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํ์ฌ ๊ฐ์ง๋๋ ์ทจ์ฝ์
Netra Security๋ ๋ค์๊ณผ ๊ฐ์ ์ทจ์ฝ์ ์ ํ์งํฉ๋๋ค:
| ID | ์ทจ์ฝ์ | ์ฌ๊ฐ๋ |
|---|---|---|
| NETRA-001 | ๋ช ๋ น์ด ์ฃผ์ | ์ฌ๊ฐ๋ |
| NETRA-002 | ์ฝ๋ ์ฃผ์ | ์ฌ๊ฐ๋ |
| NETRA-003 | ํ๋์ฝ๋ฉ ๋น๋ฐ๋ฒํธ | ๋์ |
| NETRA-004 | ํ๋์ฝ๋ฉ API ํค | ๋์ |
| NETRA-005 | ์์ ์ฝ๋ ์คํ | ์ฌ๊ฐ๋ |
| NETRA-006 | ๋ถ์์ ํ ์ง๋ ฌํ | ๋์ |
| NETRA-007 | ์ํํ ์๋ธํ๋ก์ธ์ค ์ฌ์ฉ | ๋์ |
์ํ ์ถ๋ ฅ
=== NETRA ๋ณด์ ๋ณด๊ณ ์ ===
์ด ๊ฒฐ๊ณผ: 5
ID : NETRA-001
์ฌ๊ฐ๋ : CRITICAL
๋ฌธ์ : ๋ช
๋ น์ด ์ฃผ์
์ค : 13
Code : os.system(user)
ํด๊ฒฐ ๋ฐฉ๋ฒ : Use subprocess.run(..., shell=False)
๋ฐฐ์ด ์
์ ์ ๋ถ์์ ์๊ฐ๋ณด๋ค ํจ์ฌ ๋ณต์กํฉ๋๋ค
์ฒ์์๋ ๋ณด์ ์ค์บ๋์ด ์ฃผ๋ก ํจํด ๋งค์นญ์ ๊ธฐ๋ฐํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
์ค์ ๋ก,false ์์ ์ค์ด๋ ๊ฒ์ ๊ฐ์ฅ ์ด๋ ค์ด ๊ณผ์ ์ค ํ๋์
๋๋ค.
AST๋ ๋งค์ฐ ๊ฐ๋ ฅํฉ๋๋ค
AST๋ ์์ ํ
์คํธ๊ฐ ์๋ ์ฝ๋ ๋์์ ๊ธฐ๋ฐํ ๋ถ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์ด๊ฒ์ ์ ๋ฌธ ๋ณด์ ๋๊ตฌ๊ฐ ์ ํ๋๋ฅผ ๋์ด๋ ๋ฐฉ์์
๋๋ค.
๋ณด์๊ณผ ๊ฐ๋ฐ์ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์์ต๋๋ค
๋ณด์์ ์ดํดํ๋ ๊ฐ๋ฐ์๋ ์ทจ์ฝ์ ์ด ํ๋ก๋์ ์ ๋๋ฌํ๊ธฐ ์ ์ ๋ง์ ๋ฌธ์ ๋ฅผ ์๋ฐฉํ ์ ์์ต๋๋ค.
Future Improvements
The project is still evolving.
Planned features include:
- ์ถ๊ฐ OWASP Top 10 ๊ฒ์ฌ
- ๋ค์ค ํ์ผ ํ๋ก์ ํธ ์ค์บ
- ํด๋ ์์ค ๋ถ์
- Flask๋ฅผ ์ด์ฉํ ์น ๋์๋ณด๋
- JSON ๋ฐ CSV ๋ณด๊ณ ์ ๋ด๋ณด๋ด๊ธฐ
- ์ํ ์ ์ ์์ง
- CI/CD ํตํฉ
- GitHub ์ ์ฅ์ ์ค์บ
์ต์ข ์๊ฐ
Netra Security๋ฅผ ๊ตฌ์ถํ๋ฉด์ ์ ์ ๋ถ์ ๋๊ตฌ๊ฐ ์ด๋ป๊ฒ ์๋ํ๊ณ ์ํํธ์จ์ด๊ฐ ๋ฐฐํฌ๋๊ธฐ ์ ์ ์ทจ์ฝ์ ์ด ์ด๋ป๊ฒ ํ์ง๋ ์ ์๋์ง ๋ ๊น์ด ์ดํดํ ์ ์์์ต๋๋ค.
์ด ํ๋ก์ ํธ๋ ๋จ์ํ ํจํด ๋งค์นญ ์ค์บ๋๋ก ์์ํด ์ ์ฐจ AST ๊ธฐ๋ฐ ๋ณด์ ๋ถ์ ์์ง์ผ๋ก ์งํํ์ต๋๋ค.
์์ง๋ ๊ธด ์ฌ์ ์ด ๋จ์ ์์ง๋ง, ์ด๊ฒ์ด ์ฌ์ด๋ฒ๋ณด์๊ณผ ์ํํธ์จ์ด ์์ง๋์ด๋ง์ด ํฅ๋ฏธ๋ก์ด ์ด์ ์ ๋๋คโํญ์ ์๋ก์ด ๊ฒ์ ๋ฐฐ์ฐ๊ณ ๊ฐ์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
ํ์ด์ฌ, ์ฌ์ด๋ฒ๋ณด์, ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ณด์์ ๊ณต๋ถ ์ค์ด๋ผ๋ฉด ์์ฒด ๋ณด์ ๋๊ตฌ๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์ ๊ฐ๋ ฅํ ์ถ์ฒํฉ๋๋ค. ๊ธฐ์กด ๋๊ตฌ๋ง ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ๋ง์ด ๋ฐฐ์ธ ์ ์์ต๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
python #cybersecurity #appsec #security #sast #flask #beginners #opensource