๋ฌธ์ : DreamHack โ simple-web-request ๋ถ๋ฅ: Web ๋์ด๋: ๐ฑ Sprout FLAG:
DH{c46b414ddba26adfa4606c59655bda0a18fbe260606b042b52d865e0160eea0e}
์ด๋ฆ ๊ทธ๋๋ก "๊ฐ๋จํ ์น ์์ฒญ" ๋ฌธ์ ๋ค. ํ๋ฉด์ STEP 1 / STEP 2 / FLAG ๋งํฌ ์ธ ๊ฐ๋ง ์๊ณ , ์ ํด์ง ์์๋๋ก ์ ํด์ง ํ๋ผ๋ฏธํฐ๋ฅผ ์ค์ด ์์ฒญ์ ๋ณด๋ด๋ฉด ํ๋๊ทธ๊ฐ ๋์จ๋ค. HTTP ๋ฉ์๋(GETยทPOST)์ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ผ๋ก ๋ค๋ค ๋ณด๋ ๊ฒ ๋ชฉ์ ์ธ ์ ๋ฌธ ๋ฌธ์ ๋ผ, ์ฝ๋๋ ์งง๊ณ ์ฐํ๋ ๊ฒ๋ ๊ฑฐ์ ์๋ค. ๋ค๋ง ๋จ๊ณ ์ฌ์ด๋ฅผ ์๋ ๋์ ํ ํฐ ํ๋๊ฐ ์์ด์, ๊ทธ๊ฑธ ์ด๋ป๊ฒ ์ด์ด ๋ถ์ด๋์ง๊ฐ ์ ๋ถ๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | simple-web-request |
| ๋์ด๋ | ๐ฑ Sprout |
| ๋ถ๋ฅ | Web (HTTP ์์ฒญ) |
| ์คํ | Python + Flask |
| ์ ๊ณต | app.py + ์๋ฒ |
| ํต์ฌ | ์ธ ๋จ๊ณ GETยทPOST ์ฒด์ธ + ๋จ๊ณ๋ง๋ค ์ ๋จ๊ณ๊ฐ ๋ฐ๊ธํ ๋์ ํ ํฐ ๊ฒ์ฆ |
ํ์ด ํ๋ฆ์ ๋จ์ํ๋ค. /step1 ์ ์ฌ๋ฐ๋ฅธ GET ํ๋ผ๋ฏธํฐ๋ฅผ ์ฃผ๋ฉด /step2 ๋ก ๋ฆฌ๋ค์ด๋ ํธ๋๊ณ , /step2 ๋ HTML ์์ hidden ํ ํฐ์ ๋ฐ์ ๋ด๋ ค์ค๋ค. ๊ทธ ํ ํฐ์ ๊ทธ๋๋ก /flag ์ POST๋ก ๋ค์ ์ฌ๋ฆฌ๋ฉด ํ๋๊ทธ๊ฐ ๋จ์ด์ง๋ค. ํ ํฐ์ด ํ ํ๋ฆ ์์์๋ง ์ ํจํ๋ค๋ ์ ๋ง ์ฃผ์ํ๋ฉด ๋๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ GETยทPOST ์ ๋ฆฌ๋ค์ด๋ ํธ, ๊ทธ๋ฆฌ๊ณ ์ธ์
์ด ๋ฌธ์ ๋ฅผ ํ๋ ค๋ฉด HTTP ์์ฒญ์ ๊ธฐ๋ณธ ์ธ ๊ฐ์ง๋ฅผ ๊ตฌ๋ถํ ์ค ์์์ผ ํ๋ค.
GET ๊ณผ POST. ๋ ๋ค ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๋ ๋ฉ์๋๋ค. GET์ ๋ณดํต ๋ฐ์ดํฐ๋ฅผ URL ์ฟผ๋ฆฌ์คํธ๋ง(?param=๊ฐ)์ ๋ด์ "์กฐํ"ํ ๋, POST๋ ๋ณธ๋ฌธ(body)์ ๋ด์ "์ ์ถ"ํ ๋ ์ด๋ค. Flask์์๋ request.args.get() ์ผ๋ก GET ์ฟผ๋ฆฌ๋ฅผ, request.form.get() ์ผ๋ก POST ํผ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋๋ค. ์ด ๋ฌธ์ ๋ ๋จ๊ณ๋ง๋ค ๋ ์ค ํ๋๋ฅผ ์ ํํ ๋ง์ถฐ ๋ณด๋ด์ผ ํ๋ค.
302 ๋ฆฌ๋ค์ด๋ ํธ. ์๋ฒ๊ฐ 302 ์๋ต์ Location ํค๋๋ฅผ ์ค์ด ๋ณด๋ด๋ฉด, ๋ธ๋ผ์ฐ์ ๋ HTTP ํด๋ผ์ด์ธํธ๋ ๊ทธ ์ฃผ์๋ก ๋ค์ ์์ฒญ์ ๋ณด๋ธ๋ค. Flask์ redirect(url_for(...)) ๊ฐ ์ด ์๋ต์ ๋ง๋ ๋ค. ์ด ๋ฌธ์ ์์ /step1 ํต๊ณผ ์งํ /step2 ๋ก ๋์ด๊ฐ๋ ๊ฒ ๋ฐ๋ก ์ด ๋ฆฌ๋ค์ด๋ ํธ๋ค.
์ธ์ (์ฟ ํค ์์ด๋). ๋ณดํต "์ธ์ "์ด๋ผ๊ณ ํ๋ฉด ์ฟ ํค๋ก ์ํ๋ฅผ ์ ์งํ๋ ๊ฑธ ๋ ์ฌ๋ฆฌ์ง๋ง, ์ด ๋ฌธ์ ์๋ฒ๋ ์ฟ ํค๋ฅผ ์ฐ์ง ์๋๋ค. ๋์ ๋จ๊ณ ํ ํฐ์ ์๋ฒ ์ ์ญ ๋ณ์์ ์ ์ฅํด ๋๊ณ , ๋ค์ ์์ฒญ์ด ๊ทธ ๊ฐ๊ณผ ๋ง๋์ง ๋น๊ตํ๋ค. ๊ทธ๋์ ํ ํฐ์ ์๋ต์์ ์ฝ์ด ๋ค์ ์์ฒญ์ ์ง์ ์ค์ด ๋ณด๋ด๋ ์์ผ๋ก ํ๋ฆ์ ์ด์ด์ผ ํ๋ค.
๐ฌ ์ฝ๋ ์ ์ฐฐ โ app.py
์ ๊ณต๋ app.py ๋ ๋ผ์ฐํธ ๋ค ๊ฐ๊ฐ ์ ๋ถ๋ค. ํ๋์ฉ ๋ณด๋ฉด ํต๊ณผ ์กฐ๊ฑด์ด ๊ทธ๋๋ก ๋๋ฌ๋๋ค.
@app.route("/step1", methods=["GET", "POST"])
def step1():
global step1_num
step1_num = int.from_bytes(os.urandom(16), sys.byteorder) # ํธ์ถ๋ง๋ค ์ ๋์
if request.method == "GET":
prm1 = request.args.get("param", "")
prm2 = request.args.get("param2", "")
step1_text = "param : " + prm1 + "\nparam2 : " + prm2 + "\n"
if prm1 == "getget" and prm2 == "rerequest":
return redirect(url_for("step2", prev_step_num=step1_num)) # โ ํต๊ณผ ์ step2๋ก
return render_template("step1.html", text=step1_text)
else:
return render_template("step1.html", text="Not POST")/step1 ์ GET์ผ๋ก param=getget, param2=rerequest ๋ฅผ ๋ฐ์ผ๋ฉด /step2?prev_step_num=<step1_num> ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ค. ์ฌ๊ธฐ์ step1_num ์ ํจ์์ ๋ค์ด์ฌ ๋๋ง๋ค ์๋ก ์์ฑ๋๋ 16๋ฐ์ดํธ ๋์๋ค. ์ด๊ฒ ๋ค์์ ํจ์ ์ด ๋๋ค.
์กฐ๊ฑด์ด ์ ๋ง์ผ๋ฉด ๊ทธ๋ฅ ์ ๋ ฅํ ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ทธ๋๋ก ํ๋ฉด์ ์ถ๋ ฅํ๋ค. ์ง์ ์๋ฌด ๊ฐ์ด๋ ๋ฃ์ด ๋ณด๋ฉด ๊ทธ๋๋ก ๋ฐ์ฌ๋๋ ๊ฑธ ๋ณผ ์ ์๋ค.

@app.route("/step2", methods=["GET", "POST"])
def step2():
if request.method == "GET":
if request.args.get("prev_step_num"):
try:
prev_step_num = request.args.get("prev_step_num")
if prev_step_num == str(step1_num): # โ step1์ด ๋ฐ๊ธํ ๊ฐ๊ณผ ์ผ์น?
global step2_num
step2_num = int.from_bytes(os.urandom(16), sys.byteorder)
return render_template("step2.html",
prev_step_num=step1_num, hidden_num=step2_num)
except:
return render_template("step2.html", text="Not yet")
return render_template("step2.html", text="Not yet")
.../step2 ๋ GET ์ฟผ๋ฆฌ prev_step_num ์ด ํ์ฌ step1_num ๊ณผ ๊ฐ์ ๋๋ง ๋ค์์ผ๋ก ๋๊ฒจ์ค๋ค. ํต๊ณผํ๋ฉด ์ ๋์ step2_num ์ ๋ง๋ค์ด step2.html ์ ๋๊ธฐ๋๋ฐ, ํ
ํ๋ฆฟ์ ๋ณด๋ฉด ์ด ๊ฐ์ด hidden input ์ผ๋ก ๋ฐํ๋ค.
<!-- step2.html -->
<form action="/flag" method="post">
<p>param <input type="text" name="param"/></p>
<p>param2 <input type="text" name="param2"/></p>
<input type="hidden" name="check" value="{{ hidden_num }}"> <!-- โ step2_num์ด ์ฌ๊ธฐ -->
<input type="submit"/>
</form>@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html", flag_txt="Not yet")
else:
prev_step_num = request.form.get("check", "")
try:
if prev_step_num == str(step2_num): # โ step2๊ฐ ๋ฐ๊ธํ ๊ฐ๊ณผ ์ผ์น?
prm1 = request.form.get("param", "")
prm2 = request.form.get("param2", "")
if prm1 == "pooost" and prm2 == "requeeest":
return render_template("flag.html", flag_txt=FLAG) # โ ํ๋๊ทธ!
.../flag ๋ POST๋ก check ๊ฐ ํ์ฌ step2_num ๊ณผ ๊ฐ๊ณ , ๋์์ param=pooost, param2=requeeest ์ผ ๋ FLAG ๋ฅผ ๋๋ ค์ค๋ค. ์ ๋ฆฌํ๋ฉด ํต๊ณผ ์กฐ๊ฑด์ ์ด๋ ๋ค.
| ๋จ๊ณ | ๋ฉ์๋ | ์กฐ๊ฑด |
|---|---|---|
/step1 | GET | param=getget & param2=rerequest โ step1_num ๋ฐ๊ธ, /step2 ๋ก redirect |
/step2 | GET | prev_step_num == step1_num โ step2_num ๋ฐ๊ธ, hidden input ์ผ๋ก ๋
ธ์ถ |
/flag | POST | check == step2_num & param=pooost & param2=requeeest โ FLAG |
๐งฑ ์ํฐ์นํธ โ ํ ํฐ์ ํ ํ๋ฆ ์์์๋ง ์ฐ๋ค
์ฝ๋ ์ฃผ์์ "ํ์ด์ ๊ด๊ณ์๋ ์นํ
๋ฐฉ์ง ์ฝ๋"๋ผ๊ณ ์ ํ ์๋ ๋ถ๋ถ์ด ๋ฐ๋ก step1_num / step2_num ๊ฒ์ฆ์ด๋ค. ์ด๊ฒ ์์ผ๋ฉด ๊ทธ๋ฅ /flag ์ ์ ๋ต ํ๋ผ๋ฏธํฐ๋ง POSTํ๋ฉด ๋์ด๋ผ, ํ ํฐ์ผ๋ก "์ ๋จ๊ณ๋ฅผ ์ค์ ๋ก ๊ฑฐ์ณค๋์ง"๋ฅผ ํ์ธํ๋ค.
ํจ์ ์ step1_num ์ด /step1 ์ ๋ค์ด์ฌ ๋๋ง๋ค ์๋ก ์์ฑ๋๋ค๋ ์ ์ด๋ค. ๊ทธ๋์ /step1 ์ ๋ค์ ๋ถ๋ฅด๋ ์๊ฐ ์ง์ ์ ๋ฐ์ prev_step_num ์ ๋ฌดํจ๊ฐ ๋๋ค. /step2 ์ ํ ํฐ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ทธ ๋ค์ /step2 ํธ์ถ์์ ๊ฐ๋ฆฐ๋ค. ๊ฒฐ๊ตญ STEP1 โ STEP2 โ FLAG ๋ฅผ ์ค๊ฐ์ ๋์ง ์๊ณ ํ ํ๋ฆ์ผ๋ก ์ด์ด์ผ ํ๋ค.

๐ ์ฝ์ง โ ๋งํฌ๋ฅผ ๋ฐ๋ก๋ฐ๋ก ๋๋ฌ ๋ณด๊ธฐ
์ฒ์์ ๋ฉ์ธ์ ๋งํฌ๋ฅผ ์์๋๋ก ๋๋ฌ ๋ดค๋ค. /step2 ์ /flag ๋ฅผ ๊ทธ๋ฅ ์ง์ ์ด๋ฉด ์ด๋ป๊ฒ ๋๋ ํ์ธํ๋ ์ฐจ์์ด์๋๋ฐ, ๋น์ฐํ ๋ ๋ค ๋งํ๋ค.
โถ๐ ์ฝ์ง โ /step2ยท/flag ์ง์ ์ ๊ทผ์ ์ ๋ถ Not yet
/step2 ๋ฅผ prev_step_num ์์ด ๊ทธ๋ฅ ์ด๋ฉด else ๋ถ๊ธฐ๋ก ๋น ์ ธ "Not yet" ๋ง ๋์จ๋ค. step1_num ๊ฒ์ฆ์ ํต๊ณผํ ์ ์ด ์์ผ๋ hidden ํ ํฐ๋ ์ ๋ฐํ๋ค.

/flag ๋ฅผ GET์ผ๋ก ์ด์ด๋ ๋ง์ฐฌ๊ฐ์ง๋ค. /flag ์ GET ํธ๋ค๋ฌ๋ ๋ฌด์กฐ๊ฑด "Not yet" ์ ๋๋ ค์ฃผ๊ณ , ํ๋๊ทธ๋ POST + check ํ ํฐ์ด ๋ง์ ๋๋ง ๋์จ๋ค. ๋งํฌ ํด๋ฆญ(=GET)๋ง์ผ๋ก๋ ์ ๋ ๋๋ฌํ ์ ์๋ ๊ตฌ์กฐ๋ค.

์ฌ๊ธฐ์ "์, ๋ฉ์๋์ ํ ํฐ์ ์ง์ ๋ง์ถฐ ๋ณด๋ด์ผ ํ๋๊ตฌ๋"๊ฐ ๋ถ๋ช ํด์ง๋ค.
/step1 ๋ง ๋ฐ๋ก ์ด๋ฉด ๋น ์
๋ ฅ ํผ์ด ๋ณด์ธ๋ค. ํผ์ method="get" ์ด๋ผ, ์ฌ๊ธฐ์ ๊ฐ์ ๋ฃ๊ณ ์ ์ถํด๋ ๊ฒฐ๊ตญ GET ์ฟผ๋ฆฌ๋ก ๋๊ฐ๋ค.

๐ฃ ํต์ฌ โ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด ํ ํฐ์ด ์ ์ ๋ก ์ด์ด์ง๋ค
์ฌ๊ธฐ์ ํต์ฌ ๊ด์ฐฐ. /step1?param=getget¶m2=rerequest ๋ก ๋ค์ด๊ฐ๋ฉด ์๋ฒ๊ฐ step1_num ์ ๋ง๋ ์งํ /step2?prev_step_num=<๊ทธ ๊ฐ> ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ค. ์ฆ ๋ฆฌ๋ค์ด๋ ํธ URL์ด ๋ฐฉ๊ธ ๋ฐ๊ธ๋ ํ ํฐ์ ๊ทธ๋๋ก ๋ด๊ณ ์๋ค. ๋ธ๋ผ์ฐ์ ๋ HTTP ํด๋ผ์ด์ธํธ๋ ๊ทธ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด, /step2 ๊ฒ์ฆ์ ๊ทธ๋๋ก ํต๊ณผํ๋ฉด์ step2_num ์ด ๋ฐํ ํผ์ ๋ฐ๊ฒ ๋๋ค.
์ค์ ๋ก ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ /step1?param=getget¶m2=rerequest ๋ฅผ ์น๋ฉด, ์๋์ผ๋ก /step2?prev_step_num=... ๋ก ๋์ด๊ฐ ์
๋ ฅ ํผ์ด ๋ฌ๋ค. ์ฃผ์์ฐฝ์ ๊ธด ์ซ์๊ฐ step1_num, ๊ทธ๋ฆฌ๊ณ ์ด ํ์ด์ง์ hidden input ์ step2_num ์ด ๋ค์ด ์๋ค.

์ด ํผ์ action="/flag" method="post" ์ด๊ณ hidden check ์ step2_num ์ด ์ด๋ฏธ ์ฑ์์ ธ ์๋ค. ๊ทธ๋ฌ๋ ์ด ํ๋ฉด์์ param, param2 ์นธ์ ์ ๋ต์ ๋ฃ๊ณ ์ ์ถํ๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ์์์ check + param + param2 ๋ฅผ POST๋ก /flag ์ ์ฌ๋ฆฐ๋ค. ์ค๊ฐ์ /step1 ์ด๋ /step2 ๋ฅผ ๋ค์ ๊ฑด๋๋ฆฌ์ง ์์์ผ๋ ํ ํฐ๋ ๊ทธ๋๋ก ์ ํจํ๋ค.
๐ฏ ์ต์คํ๋ก์ โ ๋ธ๋ผ์ฐ์ ๋ก ํ ๋ฒ
๊ฐ์ฅ ์์ฌ์ด ๋ฐฉ๋ฒ์ ์ ํผ์ ๊ทธ๋๋ก ์ฐ๋ ๊ฒ์ด๋ค. ๋ฆฌ๋ค์ด๋ ํธ๋ก ๋์ฐฉํ /step2 ํผ์์ param ์ pooost, param2 ์ requeeest ๋ฅผ ๋ฃ๊ณ ์ ์ถํ๋ฉด ๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ hidden check ๊น์ง ํจ๊ป POSTํ๋ฏ๋ก ์ถ๊ฐ๋ก ์๋ ๊ฒ ์๋ค.

/flag ํ๋ฉด์ ํ๋๊ทธ๊ฐ ๊ทธ๋๋ก ์ฐํ๋ค.
DH{c46b414ddba26adfa4606c59655bda0a18fbe260606b042b52d865e0160eea0e}๐ Full Exploit โ requests.Session ์ผ๋ก ์๋ํ
๋งค๋ฒ ์์ผ๋ก ํผ์ ์ฑ์ฐ๋ ๋์ , requests.Session ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ์๋ ์ถ์ ํ๊ณ hidden ํ ํฐ์ ์ ๊ท์์ผ๋ก ๋ฝ์ ์ด์ด ๋ถ์ด๋ฉด ํ ๋ฒ์ ๋๋๋ค. allow_redirects=True (๊ธฐ๋ณธ๊ฐ) ๋๋ถ์ STEP1์ 302๋ฅผ ๋ฐ๋ผ๊ฐ STEP2 ํผ๊น์ง ํ ํธ์ถ๋ก ๋๋ฌํ๊ณ , ๊ฑฐ๊ธฐ์ check ๊ฐ์ ์ฝ์ด ๊ทธ๋๋ก POSTํ๋ฉด ๋๋ค.
#!/usr/bin/env python3
# simple-web-request โ GET/POST ์์ฒญ ์ฒด์ด๋
import re, sys, requests
BASE = sys.argv[1] if len(sys.argv) > 1 else "http://host3.dreamhack.games:22341"
BASE = BASE.rstrip("/")
s = requests.Session()
# STEP1: ์ ๋ต param ๋ ๊ฐ โ 302 /step2?prev_step_num=step1_num ๊น์ง ์๋ ์ถ์
r = s.get(f"{BASE}/step1", params={"param": "getget", "param2": "rerequest"},
allow_redirects=True)
print(f"[STEP1โSTEP2] {r.url}")
print(f" status={r.status_code}")
# STEP2 ์๋ต HTML ์์ hidden check ๊ฐ(step2_num) ์ถ์ถ
m = re.search(r'name="check"\s+value="(\d+)"', r.text)
step2_num = m.group(1)
print(f"[STEP2] hidden check (step2_num) = {step2_num}")
# FLAG: POST ๋ก check + ์ ๋ต param ๋ ๊ฐ
r = s.post(f"{BASE}/flag",
data={"check": step2_num, "param": "pooost", "param2": "requeeest"})
print(f"[FLAG] status={r.status_code}")
flag = re.search(r"DH\{.*?\}", r.text)
print(f"[+] FLAG = {flag.group(0)}")requests.Session ์ ์ด ๊ฑด ์ฟ ํค ๋๋ฌธ์ด ์๋๋ผ(์ด ์๋ฒ๋ ์ฟ ํค๋ฅผ ์ ์ด๋ค) ๊ฐ์ ์ปค๋ฅ์
์ผ๋ก ํ๋ฆ์ ๊น๋ํ๊ฒ ์๊ธฐ ์ํด์๋ค. ํต์ฌ์ allow_redirects=True ๋ก STEP1์ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ฐ๋ผ๊ฐ STEP2 ํผ์ ๋ฐ๊ณ , ๊ฑฐ๊ธฐ hidden check ๊ฐ์ ๊ทธ๋๋ก STEP2๊ฐ ๋ฐ๊ธํ ํ ํฐ์ผ๋ก ์ฌ์ฌ์ฉํ๋ ๊ฒ. ์คํํ๋ฉด ๋จ๊ณ๋ณ ํ ํฐ๊ณผ ํจ๊ป ํ๋๊ทธ๊ฐ ๋จ์ด์ง๋ค.

๐ ๊ฒฐ๋ก
์์ฒญ์ ์ง์ ๋ค๋ค ๋ณด๋ ์ ๋ฌธ ๋ฌธ์ .
๋งํฌ๋ฅผ ํด๋ฆญํ๋ ๊ฒ๊ณผ, ๋ฉ์๋ยทํ๋ผ๋ฏธํฐยทํค๋๋ฅผ ์์ผ๋ก ๋ง์ถฐ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ ์ฐจ์ด๋ฅผ ์ตํ๋ ๊ฒ ์ด ๋ฌธ์ ์ ์ ๋ถ๋ค. GET์ ์ฟผ๋ฆฌ์คํธ๋ง, POST๋ ํผ ๋ณธ๋ฌธ, 302๋ ๋ฐ๋ผ๊ฐ๋ ์๋ต โ ์ด ์ ๋ง ๊ตฌ๋ถํ๋ฉด ํ๋ฆ์ด ๊ทธ๋๋ก ๋ณด์ธ๋ค.
์๋ฒ ์ํ๋ฅผ ํ ํฐ์ผ๋ก ์๋ ํจํด.
๋จ๊ณ๋ง๋ค ๋์๋ฅผ ๋ฐ๊ธํ๊ณ ๋ค์ ์์ฒญ์์ ๊ทธ ๊ฐ์ ํ์ธํ๋ ๊ตฌ์กฐ๋ ์ค์ ์๋น์ค์ CSRF ํ ํฐยท๊ฒฐ์ ํ๋ฆ ํ ํฐยทOAuth state ์ ๊ฐ์ ๋ฐ์์ด๋ค. ๋ค๋ง ์ฌ๊ธฐ์ ํ ํฐ์ ์ ์ญ ๋ณ์ ํ๋์ ๋ด์ ๋ฌ์, ๋์ ์ ์์ด๋ ์ฌ์์ฒญ์ ์ทจ์ฝํ๋ค. step1_num ์ด ํธ์ถ๋ง๋ค ๋ฎ์ด์จ์ง๋ ๊ฒ๋ ๊ทธ๋์ ํ ํ๋ฆ ์์์๋ง ์ ํจํ ๊ฒ์ด๊ณ .
๋ฐฉ์ด ๊ด์ ์์ ๋ณด๋ฉด.
์ด๋ฐ ๋ค๋จ๊ณ ๊ฒ์ฆ์ ์ ๋๋ก ํ๋ ค๋ฉด ํ ํฐ์ ์ ์ญ ๋ณ์๊ฐ ์๋๋ผ ์ฌ์ฉ์๋ณ ์ธ์ (์๋ช ๋ ์ฟ ํค๋ ์๋ฒ ์ธ์ ์ ์ฅ์)์ ๋ฌถ์ด์ผ ํ๋ค. ์ ์ญ์ ๋๋ฉด ํ ์ฌ์ฉ์์ ํ ํฐ์ด ๋ค๋ฅธ ์์ฒญ์ ๋ฎ์ด์จ์ง๊ฑฐ๋ ์์ด ๋๊ฐ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ hidden input ์ ํ ํฐ์ ๋ด๋ ค๋ณด๋ด๋ ๊ฒ ์์ฒด๋ ํํ ๋ฐฉ์์ด์ง๋ง, ๊ทธ ํ ํฐ์ด "์ด๋ค ๋จ๊ณ๊น์ง ํต๊ณผํ๋์ง"๋ง์ด ์๋๋ผ "๋๊ฐ" ํต๊ณผํ๋์ง๊น์ง ๋ฌถ์ฌ ์์ด์ผ ์๋ฏธ๊ฐ ์๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ