Fastjson最想版本RCE漏洞「漏洞分析」
1漏洞編號
CVE-2022-25845
CNVD-2022-40233
CNNVD-202206-1037
二、Fastjson知多少
萬惡之源AutoType
Fastjson的主要功能是將Java Bean序列化為JSON字符串,這樣得到的字符串就可以通過數據庫等方式進行持久化了。
但是,Fastjson在序列化及反序列化的過程中,沒有使用Java自帶的序列化機制,而是自定義了一套機制。
對于JSON框架來說,想要把一個Java對象轉換成字符串,有兩種選擇:
1、基于屬性
【一一幫助安全學習,所有資源文末領取方式一一】
①網絡安全學習路線
②20份滲透測試電子書
③安全攻防357頁筆記
④50份安全攻防面試指南
⑤安全紅隊滲透工具包
⑥網絡安全必備書籍
⑦100個漏洞實戰案例
⑧安全大廠內部教程
TOC
1.認識webpack
- webpack是一個現代的JavaScript應用的靜態模塊打包工具
- 1.模塊化
- 在ES6之前,我們要想進行模塊化開發,就必須借助于其他的工具,讓我們可以進行模塊化開發。
- 并且在通過模塊化開發完成了項目后,還需要處理模塊間的各種依賴,并且將其進行整合打包。 而webpack其中一個核心就是讓我們可能進行模塊化開發,并且會幫助我們處理模塊間的依賴關系。
- 而且不僅僅是JavaScript文件,我們的CSS、圖片、json文件等等在webpack中都可以被當做
- 2.打包
- 將webpack中的各種資源模塊進行打包合并成一個或多個包(Bundle)。
- 并且在打包的過程中,還可以對資源進行處理,比如壓縮圖片,將scss轉成css,將ES6語法轉成ES5語法,將TypeScript轉成JavaScript等等操作。
- 3.和grunt/gulp的對比
- 如果你的工程模塊依賴非常簡單,甚至是沒有用到模塊化的概念。
- 只需要進行簡單的合并、壓縮,就使用grunt/gulp即可。
- 但是如果整個項目使用了模塊化管理,而且相互依賴非常強,我們就可以使用更加強大的webpack
在這里插入圖片描述
2.webpack的安裝
- 安裝node.js(https://nodejs.org/zh-cn/)
- 查看node版本 node -v
- 全局安裝webpack npm install webpack@3.6.0 -g,指定了版本為3.6.0
- 局部安裝webpack cd 對應目錄;npm install webpack@3.6.0 --save-dev
- 其中--save-dev是開發時依賴,項目打包后不需要繼續使用
- 為什么全局安裝后,還需要局部安裝呢?
- 在終端直接執行webpack命令,使用的全局安裝的webpack
- 當在package.json中定義了scripts時,其中包含了webpack命令,那么使用的是局部webpack
3.webpack的起步
在這里插入圖片描述
- 文件和文件夾解析:
- dist文件夾:用于存放之后打包的文件
- src文件夾:用于存放我們寫的源文件
- main.js:項目的入口文件。
- mathUtils.js:定義了一些數學工具函數,可以在其他地方引用,并且使用。
- info.js:定義了一些變量信息
- index.html:瀏覽器打開展示的首頁html
- package.json:通過npm init生成的,npm包管理的文件
- mathUtils.js function add(num1,num2){ return num1 + num2; } function mul(num1,num2){ return num1*num2; } module.exports={ add, mul }
- info.js javascript<br />export const name='why';<br />export const height=180;<br />
- main.js const {add,mul}=require('./mathUtils.js'); console.log(add(20,30)); console.log(mul(20,30)); import {name,height} from './info.js'; console.log(name); console.log(height); 注:可以看到main.js引入了其它js文件
- webpack打包 webpack ./src/main.js ./dist/bundle.js
- 打包后會在dist文件下,生成一個bundle.js文件
- bundle.js文件,是webpack處理了項目直接文件依賴后生成的一個js文件,我們只需要將這個js文件在index.html中引入即可
- index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="dist/bundle.js"></script> </body> </html>
4.webpack的配置
- 目標:簡化上面的打包命令
- 1.創建webpack.config.js文件 const path=require('path') module.exports={ entry : "./src/main.js", output: { path: path.resolve(__dirname,'dist'), //動態獲取絕對路徑,__dirname是node中全局變量 filename : "bundle.js" }, }
- 2.npm init,生成package.json文件,這里面是針對當前項目的主要描述文件(里面會生成所有安裝的依賴)
在這里插入圖片描述
- 3.局部安裝webpack----cd 當前目錄;npm install webpack@3.6.0 --save-dev,生成node模塊
在這里插入圖片描述
在這里插入圖片描述
5.loader的使用
- 在開發中我們不僅僅有基本的js代碼處理,我們也需要加載css、圖片,也包括一些高級的將ES6轉成ES5代碼,將TypeScript轉成ES5代碼,將scss、less轉成css,將.jsx、.vue文件轉成js文件等等
- 對于webpack本身的能力來說,對于這些轉化是不支持的。需要webpack擴展對應的loader
- loader使用過程:
- 步驟一:通過npm安裝需要使用的loader
- 步驟二:在webpack.config.js中的modules關鍵字下進行配置
5.1 css的loader使用
在這里插入圖片描述
css<br />body {<br /> background-color:red; <br />}<br />
- 2.main.js引用 //1.使用commonjs的模塊化規范 const {add,mul}=require('./js/mathUtils.js'); console.log(add(20,30)); console.log(mul(20,30)); //2.使用ES6的模塊化規范 import {name,height} from './js/info.js'; console.log(name); console.log(height); //3.依賴css文件 require("./css/normal.css")
- 3.run build打包(報錯)
在這里插入圖片描述
- 4.https://v4.webpack.docschina.org/loaders/,配置cssloader文檔
- 5.npm install --save-dev css-loader@2.0.2
- 6.npm install style-loader@0.23.1 --save-dev
- 7.配置webpack.json.js文件
在這里插入圖片描述
- 8.index.html的使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> 你好 <h2> 你好 </h2> <script src="dist/bundle.js"></script> </body> </html>
5.2 less的loader使用(同理)
在這里插入圖片描述
@fontSize: 50px; @fontColor: orange; body{ font-size: @fontSize; color: @fontColor; }
- 2.引入less文件(main.js) //1.使用commonjs的模塊化規范 const {add,mul}=require('./js/mathUtils.js'); console.log(add(20,30)); console.log(mul(20,30)); //2.使用ES6的模塊化規范 import {name,height} from './js/info.js'; console.log(name); console.log(height); //3.依賴css文件 require("./css/normal.css") //4.依賴less文件 require("./css/special.less")
- 3.npm install less-loader@4.1.0 --save-dev 和npm install less@3.9.0 --save-dev
- 4.配置webpack.json.js文件
在這里插入圖片描述
5.3 圖片文件處理
在這里插入圖片描述
- 2.修改css文件 body { /* background-color:red; */ background-image: url("../img/timg.jpg"); }
- 3.直接打包會出錯,需要安裝url-loader包 npm install url-loader@1.1.2 --save-dev
- 4.修改webpack.json.js文件
在這里插入圖片描述
- 5.這時候打包會成功,但是換了一張大的圖片就會報錯
在這里插入圖片描述
- 6、安裝file-loader處理大文件npm install file-loader@3.0.1 --save-dev
- 7、再次打包即可成功
在這里插入圖片描述
注:可以發現,對于大的圖片打包成功會輸出到dist文件夾下,此時引用的話會找不到,需要配置下路徑
在這里插入圖片描述
- 9.另外對于生成的圖片名字太長,我們可以配置下生成規則--webpack.config.js,表示生成名字+8位哈希值+擴展名
在這里插入圖片描述
5.4 babel的使用(es6轉es5)
- 1.npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
- 2.配置webpack.json.js文件
在這里插入圖片描述
6.webpack中配置Vue
6.1 引入vue.js
- 1 . npm install vue@2.5.21 --save 因為我們后續是在實際項目中也會使用vue的,所以并不是開發時依賴
- 2 . main.js引入 //1.使用commonjs的模塊化規范 const {add,mul}=require('./js/mathUtils.js'); console.log(add(20,30)); console.log(mul(20,30)); //2.使用ES6的模塊化規范 import {name,height} from './js/info.js'; console.log(name); console.log(height); //3.依賴css文件 require("./css/normal.css") //4.依賴less文件 require("./css/special.less") //5.使用Vue進行開發 import Vue from "vue" new Vue({ el:'#app', data:{ name : 'codewhy' } })
- 3.run build(報錯)---這個錯誤說的是我們使用的是runtime-only版本的Vue,
在這里插入圖片描述
- 4.修改webpack.config.js配置,即可成功
在這里插入圖片描述
- 5.index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body > <div id="app"> 你好 </div> <h2> 你好 </h2> <script src="dist/bundle.js"></script> </body> </html>
6.2 el和template的區別
- 正常運行之后,我們來考慮另外一個問題:
- 如果我們希望將data中的數據顯示在界面中,就必須是修改index.html
- 如果我們后面自定義了組件,也必須修改index.html來使用組件
- 但是html模板在之后的開發中,我并不希望手動的來頻繁修改,是否可以做到呢?
- 定義template屬性:
- 在前面的Vue實例中,我們定義了el屬性,用于和index.html中的#app進行綁定,讓Vue實例之后可以管理它其中的內容
- 這里,我們可以將div元素中的{{message}}內容刪掉,只保留一個基本的id為div的元素
- 但是如果我依然希望在其中顯示{{message}}的內容,應該怎么處理呢?
- 我們可以再定義一個template屬性,代碼如下:
在這里插入圖片描述
- 那么,el和template模板的關系是什么呢?
- 在我們之前的學習中,我們知道el用于指定Vue要管理的DOM,可以幫助解析其中的指令、事件監聽等等。
- 而如果Vue實例中同時指定了template,那么template模板的內容會替換掉掛載的對應el的模板。
- 這樣做有什么好處呢?
- 這樣做之后我們就不需要在以后的開發中再次操作index.html,只需要在template中寫入對應的標簽即可
6.3 分離template模板
- 書寫template模塊非常麻煩怎么辦呢?
- 沒有關系,稍后我們會將template模板中的內容進行抽離。
- 會分成三部分書寫:template、script、style,結構變得非常清晰。
在這里插入圖片描述
- 1 .App.vue文件 <template> <div> <h2 class="title">{{message}}</h2> <button @click="btnClick">按鈕</button> <h2>{{name}}</h2> <Cpn/> </div> </template> <script> import Cpn from "./Cpn.vue" export default { name:"App", components: { Cpn }, data(){ return { name : 'codewhy', message:"123" } }, methods:{ btnClick(){ } } } </script> <style scoped> .title{ color:green; } </style>
- 2 .子組件Cpn.vue文件 <template> <div> <h2 class="title">我是cpn組件的標題</h2> <p>我是cpn組件的內容</p> <h2>{{name}}</h2> </div> </template> <script> export default { name:"Cpn", data(){ return { name : 'Cpn的組件的name', } }, methods:{ btnClick(){ } } } </script> <style scoped> .title{ color:green; } </style>
- 3 .main.js引入App.vue //1.使用commonjs的模塊化規范 const {add,mul}=require('./js/mathUtils.js'); console.log(add(20,30)); console.log(mul(20,30)); //2.使用ES6的模塊化規范 import {name,height} from './js/info.js'; console.log(name); console.log(height); //3.依賴css文件 require("./css/normal.css") //4.依賴less文件 require("./css/special.less") //5.使用Vue進行開發 import Vue from "vue" // import App from "./vue/app" import App from './vue/App.vue' const app=new Vue({ el:'#app', // 如果同時有el和template,會直接用template 替換掉el內容 template: <App/> , components:{ App } })
- 4 .index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body > <div id="app"> 你好 </div> <h2> 你好 </h2> <script src="dist/bundle.js"></script> </body> </html>
7.認識plugin
7.1 添加版權聲明
在這里插入圖片描述
在這里插入圖片描述
7.2 HtmlWebpackPlugin
- 目的:將index.html打包到dist中
- 1.安裝插件npm install html-webpack-plugin@3.2.0 --sava-dev
- 2.在webpack.config.js導入
在這里插入圖片描述
- 3.因為index.html的js 打包后會自動引入,所以注釋了dist 以及下面的內容 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body > <div id="app"> 你好 </div> <!-- <script src="dist/bundle.js"></script> --> </body> </html>
- 4.最后生成的如下
在這里插入圖片描述
7.3 壓縮js的插件
- 1.npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
- 2.配置webpack.config.js
在這里插入圖片描述
在這里插入圖片描述
8.plugin的使用搭建本地服務器
- webpack提供了一個可選的本地開發服務器,這個本地服務器基于node.js搭建,內部使用express框架,可以實現我們想要的讓瀏覽器自動刷新顯示我們修改后的結果。
- 不過它是一個單獨的模塊,在webpack中使用之前需要先安裝它
- npm install --save-dev webpack-dev-server@2.9.1
- 修改webpack.config.js
- devserver也是作為webpack中的一個選項,選項本身可以設置如下屬性:
- contentBase:為哪一個文件夾提供本地服務,默認是根文件夾,我們這里要填寫./dist
- port:端口號
- inline:頁面實時刷新
- historyApiFallback:在SPA頁面中,依賴HTML5的history模式
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
這樣就會實現,當文件改變的時候,頁面會自動修改,因為此時這些修改保存到了內存中,類似于java的熱部署
在這里插入圖片描述
在這里插入圖片描述
9.webpack的配置分離
- 目的:開發時,使用一個配置文件;發布時使用另一個配置文件
- npm install webpack-merge@4.1.5 --save-dev 安裝merge包,用于合并下面的配置文件
- 所以將webpack.config.js抽離成3個文件
- 1 . base.config.js const path=require('path') const webpack=require('webpack') const HtmlWebpackPlugin=require('html-webpack-plugin') const uglifyjsWebpackPlugin=require('uglifyjs-Webpack-plugin') module.exports={ entry : "./src/main.js", output: { path: path.resolve(__dirname,'../dist'), //動態獲取絕對路徑,__dirname是node中全局變量 filename : "bundle.js", //publicPath: 'dist/' }, plugins:[ new webpack.BannerPlugin('最終版權swz所有!'), new HtmlWebpackPlugin({ template:'index.html' }), //new uglifyjsWebpackPlugin() ], module: { rules: [ { test: /\.css/,//style¨E45Eloader將模塊的導出作為樣式添加到DOM中//css¨E45Eloader解析CSS文件后,使用import加載,并且返回CSS代碼//使用多個loader時,是從右向左use:¨E91E′style¨E45Eloader′,′css¨E45Eloader′¨E93E¨E125E,¨E123Etest:/¨E92E.less/, // style-loader 將模塊的導出作為樣式添加到 DOM 中 // css-loader 解析 CSS 文件后,使用 import 加載,并且返回 CSS 代碼 //使用多個loader時,是從右向左 use: ['style-loader','css-loader'] }, { test: /\.less/,//style¨E45Eloader將模塊的導出作為樣式添加到DOM中//css¨E45Eloader解析CSS文件后,使用import加載,并且返回CSS代碼//使用多個loader時,是從右向左use:¨E91E′style¨E45Eloader′,′css¨E45Eloader′¨E93E¨E125E,¨E123Etest:/¨E92E.less/, use: [{ loader: 'style-loader' // creates style nodes from JS strings }, { loader: 'css-loader' // translates CSS into CommonJS }, { loader: 'less-loader' // compiles Less to CSS }] }, { test: /\.(png|jpg|jpeg|gif)/i,use:¨E91E¨E123Eloader:′url¨E45Eloader′,options:¨E123E//當加載的圖片,小于limit時,會將圖片編譯成base64字符串形式//反之,需要使用file¨E45Eloader沒模塊進行加載limit:13000,//¨E91E¨E93E表示變量name:′img/¨E91Ename¨E93E.¨E91Ehash:8¨E93E.¨E91Eext¨E93E′¨E125E¨E125E¨E93E¨E125E,¨E123Etest:/¨E92E.m?js/i, use: [ { loader: 'url-loader', options: { //當加載的圖片,小于limit時,會將圖片編譯成base64字符串形式 //反之,需要使用file-loader沒模塊進行加載 limit: 13000, //[]表示變量 name: 'img/[name].[hash:8].[ext]' } } ] }, { test: /\.m?js/i,use:¨E91E¨E123Eloader:′url¨E45Eloader′,options:¨E123E//當加載的圖片,小于limit時,會將圖片編譯成base64字符串形式//反之,需要使用file¨E45Eloader沒模塊進行加載limit:13000,//¨E91E¨E93E表示變量name:′img/¨E91Ename¨E93E.¨E91Ehash:8¨E93E.¨E91Eext¨E93E′¨E125E¨E125E¨E93E¨E125E,¨E123Etest:/¨E92E.m?j exclude: , : { : , : { : [] } } }, { : s/,//exclude 排除,include包含/(node_modules|bower_components)/useloader'babel-loader'optionspresets'es2015'test/\.vue/,use:¨E91E′vue¨E45Eloader′¨E93E¨E125E¨E93E¨E125E,resolve:¨E123Ealias:¨E123E′vue/, : [] } ] }, :{ : { use'vue-loader'resolvealias'vue/,use:¨E91E′vue¨E45Eloader′¨E93E¨E125E¨E93E¨E125E,resolve:¨E123Ealias:¨E123E′vu: } }} e'"vue/dist/vue.esm.js"
- 2 . prod.config.js const uglifyjsWebpackPlugin=require('uglifyjs-Webpack-plugin') const webpackMerge=require('webpack-merge') const baseConfig=require('./base.config') module.exports=webpackMerge(baseConfig, {plugins:[ new uglifyjsWebpackPlugin() ] })
- 3 . dev.config.js const webpackMerge=require('webpack-merge') const baseConfig=require('./base.config') module.exports=webpackMerge(baseConfig, { devServer:{ contentBase: "./dist", inline: true } })
- 修改配置文件package.json
在這里插入圖片描述
注:以上安裝的模塊的版本要對應!!!
學習視頻: https://www.bilibili.com/video/BV15741177Eh?p=90&spm_id_from=pageDriver
在 Vue.js 中,使用 Element UI 的 `el-table` 組件實現跨頁多選功能,可以通過以下步驟實現:
1. 在 `el-table` 上添加 `@selection-change` 事件監聽器,用于監聽選擇狀態的變化。
2. 在事件處理函數中,判斷當前頁是否與上一次選擇的頁相同,如果相同則不進行多選操作。
3. 如果需要實現跨頁多選,可以在切換頁時清空已選中的數據。
下面是一個簡單的代碼示例:
```html
<template>
<div>
<el-table :data="tableData" @selection-change="handleSelectionChange" ref="multipleTable">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
</el-table>
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
:page-sizes="[10, 20, 30, 40]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
age: 27
}, {
date: '2016-05-04',
name: '王小虎',
age: 29
}, {
date: '2016-05-01',
name: '王小虎',
age: 25
}, {
date: '2016-05-03',
name: '王小虎',
age: 26
}],
currentPage: 1,
pageSize: 10,
total: this.tableData.length,
lastSelectedPage: null, // 用于存儲上一次選擇的頁碼
lastSelectedRows: [] // 用于存儲上一次選擇的數據行索引數組
};
},
methods: {
handleSelectionChange(val) {
const selectedRows=val; // 已選中的數據行索引數組
const lastSelectedRows=this.lastSelectedRows; // 上一次選擇的數據行索引數組
const isSamePage=this.lastSelectedPage===this.$refs.multipleTable.currentPage; // 判斷是否在同一頁內進行多選操作(跨頁多選需要清空已選中的數據)
const isMultiSelect=Array.isArray(selectedRows); // 判斷是否為多選操作(單選不需要判斷)
const isSameSelection=isMultiSelect && JSON.stringify(selectedRows)===JSON.stringify(lastSelectedRows); // 判斷是否選擇了相同的數據行(跨頁多選需要判斷是否選擇了相同的數據行)
const shouldClearSelection=isSamePage && isMultiSelect && isSameSelection; // 根據上述條件判斷是否需要清空已選中的數據(跨頁多選需要清空已選中的數據)
const newLastSelectedRows=shouldClearSelection && lastSelectedRows || selectedRows; // 根據上述條件更新上一次選擇的數據行索引數組(跨頁多選需要更新上一次選擇的數據行索引數組)
const newLastSelectedPage=shouldClearSelection && this.lastSelectedPage || this.$refs.multipleTable.currentPage; // 根據上述條件更新上一次選擇的頁碼(跨頁多選需要更新上一次選擇的頁碼)
this.lastSelectedRows=newLastSelectedRows; // 更新已選中的數據行索引數組(跨頁多選需要更新已選中的數據行索引數組)
this.lastSelectedPage=newLastSelectedPage; // 更新上一次選擇的頁碼(跨頁多選需要更新上一次選擇的頁碼)
},
handleSizeChange(val) { // 每頁顯示條數改變時的處理函數(無實際作用)
},
handleCurrentChange(val) { // 每頁顯示條數改變時的處理函數(無實際作用)
}
}
};
</script>
```