事很短,處理也簡單。權(quán)當(dāng)記錄一下,各位安全大大們手下留情。
最近一位客戶遇到官網(wǎng)被劫持的情況,想我們幫忙解決一下(本來不關(guān)我們的事,畢竟情面在這...還是無償?shù)貐f(xié)助一下),經(jīng)過三四輪“謙讓”最終這個任務(wù)還是落到了我這個不精通安全的人的頭上()。
客戶說通過百度跳轉(zhuǎn)官網(wǎng),首頁加載到一半時發(fā)生另一次跳轉(zhuǎn),跳到一個“賭球”網(wǎng)站去(歐洲杯最近大熱),但直接輸入域名就不會發(fā)生跳轉(zhuǎn)。
我初步嘗試了一下,除了 PC 端有這種情況外,移動端也會觸發(fā)這種跳轉(zhuǎn)...首先不要被現(xiàn)象迷惑,從首頁能夠加載到一半的情況可知,這種惡意跳轉(zhuǎn)應(yīng)該是通過代碼觸發(fā)的。
因為如果是在網(wǎng)絡(luò)層面又或者 Http Server 轉(zhuǎn)發(fā),根本就不會讓官網(wǎng)首頁出現(xiàn),因此排查的方向應(yīng)聚焦到代碼層面。
其次,通過百度訪問會觸發(fā)惡意跳轉(zhuǎn),但域名訪問不會。這不禁讓我想到對方有可能是通過 Header 中的 Referer 進行來源判斷。于是我嘗試使用 bing 搜索引擎對官網(wǎng)進行訪問,結(jié)果證實了我的想法,在 bing 訪問是不會發(fā)生跳轉(zhuǎn)的。
好了,既然是通過代碼跳轉(zhuǎn)的,那么它總要發(fā)生請求吧。究竟是從哪發(fā)生的請求呢?
為了防止跳轉(zhuǎn)過快的情況,先在百度頁面中復(fù)制一個鏈接,打開一個新的窗口并且打開開發(fā)者模式,再將鏈接復(fù)制到瀏覽器進行訪問。如下圖:
這時候就能夠?qū)⑹状卧L問的所有請求獲取到,并且在準(zhǔn)備發(fā)生自動跳轉(zhuǎn)之前你有足夠的時間來取消頁面請求,就能夠得到上圖的輸出。通過上圖的網(wǎng)絡(luò)輸出可知,其他都是正常的官網(wǎng)請求,唯獨 data.joysoo.xyz 是一個不知來路的域名。而且請求的 JavaScript 文件也足夠可疑,連名字都是經(jīng)過加密的樣子。
嗯...在截獲了當(dāng)前的信息后,讓其跳轉(zhuǎn)看看還有什么網(wǎng)絡(luò)輸出,如下圖:
噢,這個網(wǎng)站也嘗試加載 data.joysoo.xyz 的 DL1iBa6yb(這里與官網(wǎng)的 JavaScript 已經(jīng)不一樣了)。至此,從信息層面能夠通過 data.joysoo.xyz 域名可以將兩個網(wǎng)站的關(guān)聯(lián)串聯(lián)起來了,那么接下來就可通過這個域名進行代碼搜索。
將客戶網(wǎng)站的 PHP 代碼放入 VSCode 中進行全局搜索。如下圖:
這個域名恰巧只有一個 php 文件匹配成功。從這里也可以看出為什么無論從哪個頁面跳轉(zhuǎn)都會進行惡意跳轉(zhuǎn),因為這個腳本是直接植入到頁面的 ICP banner 模塊中的,而由于 ICP banner 每個頁面都內(nèi)嵌的,因此無論哪個頁面都會發(fā)生跳轉(zhuǎn)。
那么這個腳本是從哪里植入的呢?
從上圖可知,在 log 文件中也找到兩條與這個域名相關(guān)的記錄,如下圖:
呃...這里有一條 update 語句將這個腳本寫入到數(shù)據(jù)庫里面,估計是被 SQL注入了吧。
至此,整個解決思路也形成了。由于當(dāng)前的 PHP 框架會在網(wǎng)頁訪問時自動生成新的頁面,因此只需要重新更新數(shù)據(jù)庫內(nèi)容即可恢復(fù)。但是,這樣也只是治標(biāo)不治本,最最重要的還是加強對云服務(wù)器以及應(yīng)用的防護才是重中之重,不然問題還是會重新出現(xiàn)。
菜鳥入門,各位大佬輕噴,如有謬誤之處歡迎討論建議,也歡迎各位道友與我同行
"不積跬步,無以至千里;不積小流,無以成江海"
續(xù)接上篇文章,我們實現(xiàn)了一個簡單的登陸界面,但是我們的表單提示,例如用戶名等,是用的文字在按鈕上方提示的
那我們?nèi)绾稳崿F(xiàn)一個提示框用于提示呢?然后再自動聚焦到輸入框中呢?
// 是否顯示彈窗的標(biāo)識
@State private var showAlert:Bool=false;
// 在登陸按鈕之后放置彈窗
Button("登陸"){
// 切換要顯示Alert
showAlert.toggle();
// 省略一部分操作。。。
}.alert(isPresented: $showAlert){ // 這里 isPresented 綁定 showAlert變量
Alert(
title: Text("提示"), // 頂部的標(biāo)題
message: Text(res), // 彈窗的內(nèi)容,需要是一個Text,調(diào)用了我們之前定義的提示文本
primaryButton: .default(Text("取消")){// 第一個按鈕是默認類型樣式,顯示取消
// 第一個按鈕點擊后的操作
},
secondaryButton: .destructive(Text("確定")){
}
)
}
以上的代碼運行后得到如下結(jié)果
在這里插入圖片描述
以上的彈出框提示已經(jīng)解決,那么接下來需要實現(xiàn)的是彈出之后哪一個字段沒填,就讓它自動聚焦,讓用戶可以直接填寫那個字段 添加如下的代碼
// 是否聚焦到用戶名字段,注意@符號后面跟的是 FocusState,不然用到focused里面會報錯,并且不能設(shè)置默認值
@FocusState private var focusUser:Bool;
HStack{
Text("用戶名")
Spacer()
TextField("請輸入用戶名",text:$userName)
.multilineTextAlignment(.center)
// 給用戶名字段的 focused 綁定 focusUser 變量
.focused($focusUser)
}.padding(.all)
}
/// ... 省略部分代碼
Button("登陸"){
// 切換要顯示Alert
showAlert.toggle();
if(userName==""){
// 如果沒填 userName 那么切換 focusUser 的值
focusUser.toggle()
}
// 省略一部分操作。。。
}
// 。。。 省略Alert部分
此處的代碼實現(xiàn)了,如果在點擊登陸按鈕后用戶名沒有填,自動聚焦到用戶名字段
在本頁面中,共有三個字段,可以定義三個變量的形式來進行判定聚焦
但是如果有很多個字段的話就不合適了,我們可以使用枚舉的方式來進行定義
以下貼出本頁面完整的代碼
import SwiftUI
struct ContentView: View {
// 用戶名
@State private var userName:String="";
// 密碼
@State private var passWord:String="";
// 驗證碼
@State private var code:String="";
// 提示語
@State private var res:String="請輸入。。。";
// 提示語的顏色,color類型
@State private var color:Color=.red;
// 是否顯示彈窗標(biāo)識
@State private var showAlert:Bool=false;
// 聚焦到哪一個字段?
@FocusState private var focus:FocusField?;
// 定義一個 Hashable 的枚舉,因為 focused 的第二個參數(shù)需要一個hashable的參數(shù)
enum FocusField:Hashable{
case name;
case password;
case code;
case clear;
};
var body: some View {
// 整體縱向布局
VStack {
// 頁面標(biāo)題,加粗,標(biāo)題字體
Text("登陸界面").fontWeight(.bold).font(.title)
// 分隔占位,有點類似html中flex的flex:1,具體怎么用之后再看
Spacer()
// 一個橫向布局,表單項名稱-分隔占位-以及表單項
// 給一個 .all 的 padding,不然不好看
HStack{
Text("用戶名")
Spacer()
TextField("請輸入用戶名",text:$userName)
.multilineTextAlignment(.center)
// focused 綁定 focus變量,當(dāng)該變量為 .name 時
.focused($focus,equals: .name)
}.padding(.all)
HStack{
Text("密碼")
Spacer()
// secure field 跟 TextField基本類似,只是隱藏輸入的內(nèi)容
SecureField("請輸入密碼",text:$passWord)
.multilineTextAlignment(.center)
.focused($focus, equals: .password)
}.padding(.all)
HStack{
Text("驗證碼")
Spacer()
TextField("請輸入驗證碼",text:$code)
.multilineTextAlignment(.center)
.focused($focus, equals: .code)
}.padding(.all)
Spacer()
// 提示語和button在一起
Text(res).foregroundColor(color)
Button("登陸"){
showAlert.toggle();
color=.red
// button 的點擊事件action,做一個簡單的判斷
// 修改 res 的名稱,以及res的顏色
if(userName==""){
res="請輸入用戶名!";
return ;
}
if(passWord==""){
res="請輸入密碼!"
return ;
}
if(code==""){
res="請輸入驗證碼";
return ;
}
color=.green;
res="登陸成功"
// 清空表單數(shù)據(jù)
userName="";
passWord="";
code="";
}.buttonStyle(.bordered)
.alert(isPresented: $showAlert){
Alert(
title: Text("提示"),
message: Text(res),
primaryButton: .default(Text("取消")),
secondaryButton: .destructive(Text("確定")){
if(res=="請輸入用戶名!"){
// 沒有用戶名
focus=.name
}
if(res=="請輸入密碼!"){
focus=.password
}
if(res=="請輸入驗證碼!"){
focus=.code
}
if(res=="登陸成功" || res=="請輸入。。。"){
focus=.clear
}
}
)
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
運行得到以下的結(jié)果
在這里插入圖片描述
HTML 的 tabindex 屬性開發(fā)過程中一般不會使用到,最近開發(fā)中有個需求兼顧富交互,便總結(jié)了一下。本篇文章同時收錄在我的【前端知識點】中,Github鏈接請點擊閱讀原文直達,歡迎 Star
兼容性:Safari不支持!
在我們?nèi)粘J褂镁W(wǎng)頁的過程中,可以通過鍵盤控制一些元素的聚焦,從而達到便捷訪問的目的
element 分為 focusable 和 非focusable ,如果使用了tabindex就可以改變相關(guān)的行為
在HTML中有6個元素默認支持聚焦:
以上的元素默認都可以使用 Tab 鍵,以及 JS focus() 方法聚焦
document.querySelector("a").focus();
使用 tab鍵 進行聚焦元素時,聚焦的順序等于元素在代碼中的出現(xiàn)先后順序,當(dāng)我們進行富交互優(yōu)化時,就需要用到 tabindex 這個屬性來幫助我們進行更好用戶體驗的優(yōu)化了
①元素是否能聚焦:通過鍵盤這類輸入設(shè)備,或者通過 JS focus() 方法
②元素什么時候能聚焦:在用戶通過鍵盤與頁面交互時
通俗來說:就是當(dāng)用戶使用鍵盤時,tabindex用來定位html元素,即使用tab鍵時焦點的順序。
tabindex理論上可以使用在幾乎所有元素上
tabindex 有三個值:0,-N(通常是-1),N(正值)
tabindex 決定聚焦順序
// HTML
<button type="button" tabindex="1">tabindex === 1</button>
<button type="button" tabindex="999">tabindex === 999</button>
<button type="button" tabindex="0">tabindex === 0</button>
// HTML
<button type="button" tabindex="0">tabindex === 0</button>
<button type="button" tabindex="1">tabindex === 1</button>
<button type="button" tabindex="999">tabindex === 999</button>
<button type="button" tabindex="0">tabindex === 0</button>
tabindex 決定是否聚焦
// HTML
<button type="button">未設(shè)置tabindex</button>
<button type="button" tabindex="-1">tabindex === -1</button>
<button type="button" tabindex="0">tabindex === 0</button>
<button type="button" tabindex="1">tabindex === 1</button>
tabindex 與JS編程聚焦
// HTML
<button type="button" @click="clickBtn()">點擊讓DIV聚焦</button>
<div id="FocusDiv" ref="FocusDiv" tabindex="-1">這是一個div</div>
// JS
clickBtn: function() {
document.getElementById('FocusDiv').focus();
}
針對自定義標(biāo)簽進行富交互優(yōu)化
針對特定節(jié)點禁止聚焦操作
復(fù)雜列表控制聚焦順序
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。