Day 75 (Week11), 2021/06/25 (Friday)
學習時數:10 hr
Done
- [x] w11 [BE101] 留言板 - 修正問題篇
- 實作 hash 密碼、htmlspecialchars、prepared statement
- [x] w11 [BE101] 留言板 - 新增功能篇
- 實作 SQL join 語法、編輯留言
To Do @ this week
- [ ] w11 hw1 留言板
- [ ] w11 hw2 部落格
學習心得紀錄
Objective 客觀
修正問題篇:hash、htmlspecialchars、SQL injection
其實這邊也花滿多時間在研究如何攻擊,有嘗試攻擊看看第九週做的留言板,使用 <script>alert('');</script>
有可能會被導到釣魚網站,若沒有使用 hash 雜湊保護密碼,可能會被有心人士盜走資料庫的使用者密碼,如果沒有解決 SQL injection 字串拼接的特性,留言板可能就會被拿來打 MySQL 的指令,這樣就可以盜取一些使用者資料。
htmlspecialchars
如果沒有把輸入的文字把符號經過編碼轉換顯示出的話,可能可以執行一些 JavaScript 與 HTML 的 code,這樣可能就會有資料洩漏的危險,例如可能使用 <script>alert(location.href='https://xxx.com');</script>
,被導到不知名的網站。
hash 雜湊
其實有思考了一下,在註冊時,密碼要經過雜湊後再存入 database,然後還要記得帶上 token,這樣切回留言版主頁的時候,才是登入的狀態。
登入時,要驗證經過 hash 的密碼,幸好 PHP 內有內建的 password_verify(string $password, $hash password)
,而且其值為 boolean 值,若相符,就會回傳 true,若不符,就可以帶上 querystring 回傳,然後在 login.php 上顯示「帳號或密碼輸入錯誤」。
一開始覺得輸入錯誤的顯示很難理解,不過後來一遍又一遍的練習,就有比較熟悉,不過後來發現在編輯暱稱那邊,因為寫提示輸入錯誤的區塊與留言為空的錯誤區塊不同,所以有稍微卡了一下 query string 要怎麼帶上。
prepared statement
有嘗試當當攻擊的駭客,來攻擊看看資料庫,結果發現真的要對 SQL 的語法很熟悉,才可以千變萬變,不過可以利用 prepared statement 把輸入的值變成字串再放入 SQL 語法,就不會有被客戶端利用 SQL 語法拿取資料的疏失。
其實在 prepared statement 的指令上想滿久的,包括先預備query、帶上變數、再執行query,但這只是執行 query($result = $stmt->execute();),如果要進一步在資料庫裡撈取資料,還需要使用
$result = $stmt->get_result(),若要拿取資料在 PHP 使用,則還需要使用
fetch_assoc(),因為在上面有命名兩次
$result,有幾度以為有
$result的參數,就是取到了 data,可以在 PHP 使用,但這還只是撈 data,要在 PHP 使用,還需要多一個步驟:
fetch_assoc()`。
編輯暱稱
其中有遇到幾個問題,就是在實作編輯留言的按鈕級文字輸入框時,因為排版排在Hi~<nickname> [EDIT Nickname]
,<nickname>
就是使用者的暱稱,然後 [EDIT Nickname]
後面這一串就是編輯暱稱及文字輸入框,如果暱稱太長的話,後面的編輯暱稱排版就會跑掉,所以調整了一下方式,讓暱稱太長的話,也不置於跑版。
另外就是,編輯暱稱時,要按送出按鈕,所以就需要的標籤,一開始沒有注意,我把編輯暱稱的表單放在送出留言的表單內,形成巢狀的,想說奇怪,怎麼在 dev tool 上看不到第二個 標籤,後來才知道原來巢狀層次的兩個的 標籤會讀不懂,後來就把內層的 拉出來,放在別的位置就可以了。
SQL JOIN
有嘗試使用 left join
的 SQL 指令,但可能是拼接太長,有時候有誤,可能還是要拿到 MySQL 實際去檢索看看,是哪裡出錯會比較保險。
例如:
'select '.
'C.id as id, C.content as content, '.
'C.created_at as created_at, U.nickname as nickname, U.username as username '.
'from jean_comments as C ' .
'left join jean_users as U on C.username = U.username '.
'order by C.id desc’;
編輯留言
在 handle_update_comment.php
中,要 UPDATE 的資料是以相同 id(...where id = ??
) 的留言條上修改內容,我一開始是 username(INSERT ...SET content=xx where username=xx
),然後我就發現只要是我自己留言的地方,內容都改成一模一樣的了,我就知道出錯了QQ。
我覺得這個稍微難一點的原因是要帶上 comments 的 id,但是一開始我沒有注意到,找了滿久才發現:原來可以在表單內隱形(type='hidden'
)提交 id,這樣就剛好 POST 了 留言的 id 編號跟編輯後的新留言。
另外是編輯留言的文字框,如果空的(我在想要不要加入:跟原本內容相同)的話,要顯示填寫不完整的錯誤,結果忘記在 query string 帶上 id,就會發現出現「填寫不完整」的錯誤後,要送出留言時,好像會不認得 id 是多少,不過這個問題在表單內隱形提交 id 後,好像就解決這個問題了。
感受
今天意外的實作滿久的,中間有休息一兩個小時,十點本來想休息了,結果看到編輯留言的功能很掉漆,只差一點點就成功了,所以又多弄一個小時到十一點QQ,完全忘記要預留一點時間寫每日報告...
哇!明天下午是小樹屋線上聚會,太早填單,差點忘記QQ,幸好助教有在 mattermost 上提醒,我前幾天還想說這週末可能都要奉獻給作業了,結果赫然發現有半天的時間有線上小樹屋聚會,所以今天要至少努力到快完成「留言板新增功能」的部分,經過一番努力,剩下分頁與刪除留言。
Decisional 決定行動
希望明天早上可以完成分頁與刪除留言,然後下午快樂的參加小樹屋聚會!