談談JS中的函數劫持

2020-12-25 TechWeb

說到劫持,第一反應可能是什麼不好的東西。函數劫持並不邪惡,關鍵是看使用的人。雖然這個概念在前端領域使用較少,但是在安全領域、自定義業務等場景下還是有一定的使用價值的。所以,這一篇文章將會和大家一起去了解一下JS中的函數劫持是什麼,有什麼用。

基本概念

函數劫持,顧名思義,即在一個函數運行之前把它劫持下來,添加我們想要的功能。當這個函數實際運行的時候,它已經不是原本的函數了,而是帶上了被我們添加上去的功能。這也是我們常見的鉤子函數的原理之一。

乍一看上去,這很像是函數的改寫。函數的改寫也可以理解為是函數劫持的一種,但是這種方式太噁心了。作為一個劫持者,在綁票獲得好處以後也應該遵守職業道德,把人原封不動地還回去,所以我們得在合適的地方把函數原本的功能給重新調用回來。

推而廣之,其實「劫持」這一概念我們經常會遇到,比方說某網站被運營商劫持了,在瀏覽該網站的時候會彈出運營商的廣告。

舉例分析

現在我們來舉個簡單的例子,劫持一下alert()函數,為它增添一點小小的功能:

let warn = alert window.alert = (t) => {     if (confirm('How are you?')) warn(t) }  alert('Help me...!!!')  

可以打開開發者工具嘗試一下這個例子,你會發現只有你在confirm裡面點擊了OK,才會彈出Help me...!!!。

接下來我們把這部分的內容封裝一下,成為一個通用的函數:

const hijack = (obj, method, fun) => {   let orig = obj[method]   obj[method] = fun(orig) }  

首先我們定義了一個hijack函數,它會先把原函數給保存下來,然後執行自定義函數,而原函數將會在自定義函數內部進行調用。

然後我們來劫持confirm()函數:

hijack(window, 'confirm', (orig) => {   return (text) => {     alert('HELP ME PLZ!!!')     if (orig.call(this, text)) {       alert('YOU SEEMS FINE AND I AM LEAVING, GOOD BYE!')     } else {       alert('HOLD ON! I AM COMING!!')     }   } })  

這段函數的功能很簡單就不詳細說明了,直接調用confirm()你就知道了。

反劫持

新建一個頁面,打開你的開發者工具控制臺,輸入alert,你會看到這樣的輸出:

function alert() { [native code] } 

然後使用本文開頭的那段代碼,把alert()劫持一下,再重新在控制臺輸入alert,你會看到這樣的輸出:

function (t) => {     if (confirm('How are you?')) warn(t) }  

通過上述的例子可以知道,要看一個函數是否被劫持了,只需要直接把它列印出來即可。針對系統原生的函數,[native code]即代表它是純淨無汙染的。

函數劫持的作用

除了為函數增加功能以外,還能夠利用函數劫持去追蹤惡意用戶的信息。一般的XSS攻擊會先利用alert()等能夠輸出信息的方法進行測試,這時候我們可以先對原生alert()進行劫持,向其輸入追蹤信息的代碼,最後才把原函數釋放出去。當惡意用戶在測試alert()的時候就會立即被我們追蹤,而他本人卻無從察覺。

後記

關於JS的函數劫持,也不是什麼新鮮的東西,只是在最近的工作中遇到了這個知識點感覺比較陌生,所以花了一些時間進行了研究,並把結果記錄下來。如果發現有什麼錯漏的地方歡迎指正!

感謝你的閱讀,歡迎關注我的專欄,我將不定期分享自己的學習體驗,開發心得,搬運牆外的乾貨。下次見啦!

參考資料:

javascript 函數劫持 | 神奇輝 JavaScript函數劫持- 謝燦勇 Need to hook into a javascript function call, any way to do this?

點讚 0

相關焦點

  • 【第721期】談談JS中的函數劫持
    正文從這開始~說到劫持,第一反應可能是什麼不好的東西。函數劫持並不邪惡,關鍵是看使用的人。雖然這個概念在前端領域使用較少,但是在安全領域、自定義業務等場景下還是有一定的使用價值的。所以,這一篇文章將會和大家一起去了解一下JS中的函數劫持是什麼,有什麼用。
  • js中對函數的深入理解(下)
    在js函數中,有一個特殊的對象this,this引用的就是函數執行的環境對象,當在全局作用域中的時候,this指向的對象就是window;這裡getName函數的作用域是window,當我們直接調用該函數的時候,this指向的是window對象
  • 怎麼在click事件中調用多個js函數
    源 / php中文網      源 / www.php.cnjs中的click事件想要實現調用多個函數的功能,我們可以使用addEventListener()方法。也就是說如果要在按鈕的單擊事件中調用或執行多個函數,就可以使用JavaScript addEventListener()方法。下面我們就結合具體的代碼示例,給大家介紹js中的click事件調用多個函數的實現方法。代碼示例如下:<!
  • 高階函數不會用?教你JS中最實用的幾個高階函數用法
    /index.js"></script></body>// index.js// 回調函數// 異步請求let getInfo = function(keywords, callback) { $.ajax({ url: 'http
  • 人人都能看懂的鴻蒙 「JS 小程序」 數據綁定原理|解讀鴻蒙源碼
    在ace_lite_jsfwk代碼倉庫的packages/runtime-core/src目錄中實現了一個 ViewModel 類來完成數據劫持。ViewModel 類packages/runtime-core/src/core/index.js構造函數主要工作就是依次解析唯一參數 options 中的屬性欄位:
  • 把Node.js 中的回調轉換為 Promise
    JavaScript 將這些運行時間很長的任務轉移到瀏覽器或 Node.js 環境中的其他進程中。這樣它就不會阻止其他代碼的執行。通常異步函數會接受回調函數,所以完成之後可以處理其數據。舉個例子,我們將編寫一個回調函數,這個函數會在程序成功從硬碟讀取文件之後執行。
  • js代碼優化之編程函數
    在編程的世界中,有這樣的一個原則,簡稱二八定律二八定律:影響程序的80%性能的往往是20%的代碼在js的編寫過程中,函數設計就相當於那20%,時刻影響著你的代碼,可以說是至關重要。那麼對於函數的設計原則,你又了解多少?1.
  • 把 Node.js 中的回調轉換為 Promise
    JavaScript 將這些運行時間很長的任務轉移到瀏覽器或 Node.js 環境中的其他進程中。這樣它就不會阻止其他代碼的執行。通常異步函數會接受回調函數,所以完成之後可以處理其數據。舉個例子,我們將編寫一個回調函數,這個函數會在程序成功從硬碟讀取文件之後執行。
  • Koo.js加入回調函數支持,實現自定義功能擴展
    Koo.js原創標籤驗證插件基於Jquery開發,為KooTeam.com而生,取名Koo.js
  • 10個非常實用的JS工具函數
    performance.memory 包含內存信息,是Chrome中添加的一個非標準擴展,在使用時需要注意。t.responseStart - t.navigationStart).toFixed(0), 'domready時間': (t.domContentLoadedEventEnd - t.navigationStart).toFixed(0), 'onload時間': (t.loadEventEnd - t.navigationStart).toFixed(0), 'js
  • JS 中的 with 關鍵字
    中的with關鍵字,很多小夥伴們的第一印象可能就是with關鍵字的作用在於改變作用域,然後最關鍵的一點是不推薦使用with關鍵字。基本說明在js高級程序設計中是這樣描述with關鍵字的:with語句的作用是將代碼的作用域設置到一個特定的作用域中,基本語法如下:with (expression) statement;使用with關鍵字的目的是為了簡化多次編寫訪問同一對象的工作,比如下面的例子:var qs = location.search.substring
  • 網站劫持問題排查指南
    本文主要包括以下內容,請各位對號入座: ①、兩個真實案例教你如何排查劫持 ;②、排查劫持三步走秘籍 ;③、利用劫持手段將用戶留在站內也是不允許的 ;④、小結。1、我真的沒有做劫持,為什麼會收到劫持的站內信提醒?你的網站可能是被第三方廣告劫持了。
  • 在 Node.js 7 中甩掉 Callback Hell
    在幾個月之前,V8 引擎就實現了對 async/await 關鍵字的支持,Node.js 7中的 V8 經過幾次更新,終於在上一個 night build 版本中加入對為了解決 callback hell(回調地獄),程式設計師們一直在努力,從最早的回調函數,到 Promise 對象,再到 Generator 函數,每次都有所改進,但又讓人覺得不徹底 —— 因為使用它們之前都需要理解抽象的底層運行機制。
  • 「驅動人生」劫持事件與Mykings家族活動的關聯分析
    網絡基礎設施的重疊在對「驅動人生」劫持事件下載木馬的域名dl.haqo.net進行關聯分析時,我們注意到其中一個子域名js.haqo.net,在360威脅情報中心的ALPHA平臺中被打上Mykings的標籤,該域名解析到IP 81.177.135.35 。
  • 在Node.js中,使用Promise.prototype.finally
    由此看來,將其放入Node.js僅是時間問題。本文將向您展示:如何使用Promise.prototype.finally()以及如何編寫自己的簡化polyfill。.finally()在撰寫本文時,該功能尚未包含在任何Node.js版本中,但promise.prototype.finally在npm上的模塊具有polyfill。上面的腳本將同時列印「已完成」和「已拒絕」,這是因為onFinally在實現promise時將調用處理程序,而不管promise是實現還是拒絕。
  • 是否還在疑惑Vue.js中組件的data為什麼是函數類型而不是對象類型
    //又創建了一個Vue實例,會調用上面的定義的函數let vm2 = new Vue()//此時vm2是這樣的vm2 = { //這裡的data,是先獲取了函數Vue中的data(data的值為函數),然後得到了data的返回值 data: {  name: '李四',  age: '55' } }
  • 實戰:在Node.js和Vue.js中構建文件壓縮應用程式
    Node.js為我們提供了一個模塊來協助文件壓縮。在本文中,我們將構建一個應用程式,用戶可以在該應用程式中上傳他們想要壓縮的文件,然後使用Node.js Zlib模塊下載該文件的壓縮版本。回調函數由任何可能的錯誤和壓縮響應組成。得到Zlib響應後,我們創建一個文件並將響應保存在 compressed 目錄中,該文件將具有 .gz文件擴展名,因為它用於標識Zlib壓縮。
  • 面試官:聊聊對Vue.js框架的理解
    本文為一次前端技術分享的演講稿,所以盡力不貼 Vue.js 的源碼,因為貼代碼在實際分享中,比較枯燥,效果不佳,而更多的是以圖片和文字的形式進行表達。分享目標:了解 Vue.js 中的 Virtual DOM 及 Diff 原理分享keynote:Vue.js框架原理剖析.key原文地址Vue.js概述Vue 是一套用於構建用戶界面的漸進式
  • 一個高性能js動畫庫velocity.js簡介
    一、為什麼是velocity不是jquery時下,如何快速製作js動效,許多人可能會首先想到使用jquery。jquery的就是如此流行。因此要製作高性能js動畫,可能不得不放棄jquery,轉而使用原生js製作動畫。那有沒有一種js高性能動效庫,既像jquery一樣簡單易用,動畫又高性能?這就是velocity.js動畫庫了。
  • 如何在JavaScript中實現模塊化
    JavaScript是目前web前端開發中的核心語言,隨著我們前端頁面功能複雜化之後,前端也進入了工程化開發。今天我和大家談談如何在JavaScript中實現模塊化。JavaScript模塊化首先我們來談談為何要在JavaScript中模塊化?