请求列出指定服务器上的可用功能失败_滥用 ESI 详解(上)

3b7bbf3a93fcd612c6ae275b2eb0d907.gif

在进行安全性评估时,我们注意到了标记语言 Edge Side Includes (ESI)中的一个意外行为,这种语言用于许多流行的 HTTP 代理(反向代理、负载平衡器、缓存服务器、代理服务器)。我们发现成功的 ESI 攻击可以导致服务器端请求伪造(SSRF)、各种绕过 HTTPOnly cookie 缓解标志的跨站脚本向量(XSS)和服务器端分布式拒绝服务攻击。我们称这种技术为 ESI 注入。

通过我们的测试,我们发现了十几种流行的可以处理 ESI 的产品: Varnish、 Squid Proxy、 IBM WebSphere、 Oracle fusion / weblogic、 Akamai、 Fastly、 F5、 Node.js、 LiteSpeed 和一些特定语言的插件。并非所有这些都默认启用了 ESI,但下面将进一步讨论这个问题。

784f70a0255e2a69b7fb101cd56a66c1.png什么是Edge Side Includes(ESI) ?

ESI 语言基于了一小部分 XML 标签集合,在许多流行的 HTTP 代理解决方案中使用,通过启用 Web 内容的高速缓存来解决性能问题。ESI 标签用于指示反向代理(或缓存服务器)获取已缓存模板的网页的更多信息。这些信息在提供给客户端之前可能来自另一台服务器。这允许完全缓存的页面包含动态内容。

616a1a80c164fc655600479a7f457b5e.png

ESI  的一个常见用例是为那些基本上是静态的页面提供动态数据片段。ESI  允许开发人员用 ESI 标记替换页面的动态部分,从而增加了缓存灵活性。因此,在请求页面时,代理将处理并获取 ESI 标记,从而确保后端应用程序服务器的性能。

下面的图片可用于演示 ESI 的一个典型用例,即天气网站将缓存城市天气页面的内容。然后,动态数据将被它们各自指向 API 端点 URL 的 ESI 标记替换。

c6ea3e7c7d2f93295c2c3c5b1727c131.png

通过 ESI 构建网页的演示

ESI  的语法相当简单。上一个例子的 HTML 文件看起来是这样的:

  The Weather Website

  Weather for

  Monday:

  Tuesday:

[…]

最初的 ESI 规范可以追溯到2001年,每个供应商的实现差异很大。每个产品的特性集是不同的; 一些产品将缺少一些特性,但在其他产品中会出现。你可以在这里阅读关于原始 ESI 规范的更多信息: http://www.w3.org/tr/ESI-lang。它描述了标记语言的用法和常用特性。各种供应商,包括 Akamai 和 Oracle,也在规范之外增加了额外的功能。

784f70a0255e2a69b7fb101cd56a66c1.png问题所在

HTTP 代理不能区分由上游服务器提供的合法 ESI 标记和在 HTTP 响应中注入的恶意标记。换句话说,如果攻击者能够成功地在 HTTP 响应中反射 ESI 标记,那么代理将盲目地解析和计算它们,相信它们是来自上游服务器的合法标记。

为了让 ESI 解析器处理 ESI 标记,解析器不能对小于号和大于号的字符进行编码或转义。如今,web 应用服务器通常会避开用户可控的特殊字符,以缓解 XSS 攻击。虽然这将有效地阻止被代理程序解析的 ESI 标记,但 ESI 标记有时可以被注入到非 HTML 的 HTTP 响应中。实际上,ESI 的一个现代特性是允许开发人员向缓存和静态数据源添加动态内容,比如 JSON 对象和 CSV。在 Fastly 的博客上可以找到关于 ESI + JSON 的详尽教程,教程的内容显示可以配置 ESI 解析器来处理 JSON 对象中的 ESI 标记。由于现代框架会尝试将它们的转义工作置于上下文环境中,所以 API 端点允许 JSON 属性中类似 HTML 的字符串并不罕见,因为它们不应该被浏览器解释为 HTML。但是,这允许攻击者破坏反射在带有 ESI 标记的 JSON 响应中的输入,代理将在传输过程中对其进行解释。

前面的场景非常罕见,因为它不代表任何已分析的支持 ESI 的产品的默认行为。大多数常见的攻击向量将由后端服务器反射 ESI 标记,然后由启用 ESI 的负载均衡器或代理进行处理。显然,如果对用户输入进行了适当的清理(为了减轻 XSS 攻击,应该这样做) ,则代理将对 ESI 标记进行编码,并且永远不会对其进行处理。

784f70a0255e2a69b7fb101cd56a66c1.pngESI 注入的副作用

让我们来看看一些注入的常见场景,以及它们可以用来做什么:

服务器端请求伪造(SSRF)

可以说,ESI 规范最常见和最有用的特性是 include 的使用。ESI 的 include 是一个标签,当代理或负载均衡器处理这些标记时,执行另一个 HTTP 请求来获取动态内容。如果攻击者可以向 HTTP 响应添加 ESI include 标记,则可以在代理服务器(而不是应用程序服务器)的上下文中有效地执行 SSRF 攻击。

例如,这个有效载荷可以用于在 HTTP 代理上执行 SSRF:

如果收到 HTTP 回调,那么代理服务器容易受到 ESI 注入的攻击。如下面所讨论的,ESI 实现有所不同。有些支持 ESI  的服务器不允许来自没有白名单的主机的 include 标签,这意味着你只能对一台服务器执行 SSRF。这在下面的 “变种实现” 一节中进行了讨论。下面的图表详细说明了攻击者如何利用 ESI 来执行 SSRF:

0092047975b9e208d22220c3a0f4010b.png

典型的 ESI 注入可以导致 SSRF

1、攻击者通过带有 ESI 有效载荷的代理服务器执行请求,试图让后端服务器在响应中反射该请求

2、代理服务器接收请求并将其转发到适当的后端服务器

3、应用程序服务器在响应中反射 ESI 有效载荷,并将该响应发送到代理服务器

4、代理服务器接收到响应并进行解析,检查是否存在任何 ESI 标记。代理服务器解析反射的 ESI 标记,并发起对evil.com 的请求。

5、代理服务器接收来自evil.com 并将其添加到后端服务器的初始响应中。

6、代理服务器将完整响应发送回客户端

绕过客户端 XSS 过滤器

客户端 XSS 过滤器通常通过比较请求的输入和响应来工作。当部分 GET 参数在 HTTP 响应中回显时,浏览器将启动一系列安全措施,以确定是否反射了潜在的 XSS 有效载荷。如果浏览器执行的启发式算法将有效载荷识别为 HTML 或 Javascript,那么它就失效了,攻击也就失败了。

然而,Chrome 的 XSS 保护并不知道 ESI 标记,因为它们从未打算在客户端进行处理。通过执行一些 ESI 魔法,可以将 XSS 有效载荷的部分分配给 ESI 引擎中的变量,然后将它们打印回来。ESI  引擎将在服务器端构建恶意 Javascript 有效载荷,然后将其全部发送到浏览器。这将绕过 XSS 过滤器,因为发送到服务器的输入不会按原样返回到浏览器。让我们分析一个简单的有效载荷:

x=>alert(/Chrome%20XSS%20filter%20bypass/);>

操作符在服务器端 ESI 变量中存储任意值。然后可以使用 $(variable_name) 操作符访问这个变量。在前面的示例中,var1 变量存储值 cript。然后将该值打印回来,以完成有效的脚本 HTML 标记。然后返回的有效载荷将以如下方式返回:

00d76167f1cb41ef7357276d12f75439.png

有些 ESI 实现不支持 ESI 变量,因此会使该技术失效。当 include 可用时,并且可以将它们指向外部域时,可以简单地包含一个包含 XSS 有效载荷的外部页面。下面的示例描述了使用 ESI 包括的典型 SSRF 到 XSS 攻击。 

poc.html:

然后,注入 ESI 标签来包含页面:

GET /index.php?msg=

SSRF  将获取 poc. html 页面并在网页中显示它,然后将有效载荷添加到 DOM 中。

绕过 HttpOnly Cookie 标志

通过设计,代理和负载均衡等 HTTP 代理可以访问完整的 HTTP 请求和响应。这包括浏览器或服务器发送的所有 cookie。ESI  规范的一个有用的特性是能够在 ESI 标记内的传输过程中访问 cookie。这允许开发人员在 ESI 引擎中引用 cookie,通过利用 cookie 的状态性使它们具有更大的灵活性。

这个特性增加了一个重要的攻击向量: cookie exfilling。通过 Javascript 引擎窃取 cookie 的一个众所周知的对策是使用 HTTPOnly 标志。当在创建 cookie 时指定这个标志时,将拒绝 Javascript 引擎访问 cookie 及其值的能力,从而防止 XSS 攻击窃取 cookie。由于 ESI 是在服务器端处理的,因此当这些 cookie 从上游服务器传输到代理程序时,可以引用它们。一个攻击向量是使用 ESI 的 include 在 URL 中将 cookie 提取出来。假设 ESI 引擎正在处理以下有效载荷:

在服务器 evil.com 的 HTTP 日志中,攻击者会看到:

127.0.0.1 evil.com - [08/Mar/2018:15:20:44 - 0500] "GET /?cookie=bf2fa962b7889ed8869cadaba282 HTTP/1.1" 200 2 "-" "-"

通过这种方式,设置了 HTTPOnly 标志的 cookie 可以在没有 Javascript 的情况下被提取出来。

784f70a0255e2a69b7fb101cd56a66c1.png变种实现

如前所述,不同厂商的 ESI 实现差异很大。不同产品的特性集不同,有些特性的实现方式也不同。我们测试了一些产品,以确定可能针对支持 ESI  的软件进行的攻击,并生成了下面的表格。

2de1ad23daee899ae79e33433238812c.png

该表格的列如下所示:

Includes

这一列表示是否在 ESI 引擎中实现了   运算对象。

Vars(变量)

这一列表示是否在 ESI 引擎中实现了 运算对象。

Cookie

这一列表示 ESI 引擎是否可以访问 cookie。

需要上游服务器的 HTTP 头

这一列表示 ESI 是否需要上游服务器的标头才能运行。除非上游应用程序服务器提供了 HTTP 头,否则代理项不会处理 ESI 语句。

主机白名单

这一列表示的 ESI 的 include 运算对象只针对白名单列出的服务器主机起作用。如果启用了主机白名单的功能,那么攻击者就不能使用 ESI include 对除白名单主机以外的主机执行 SSRF 攻击。

以下章节将会更详细地介绍 ESI 的实现及特定于供应商的特性。

Squid3

Squid 的 ESI 文档几乎不存在,因此我们必须使用源代码来查找 ESI 特性。在测试各种 ESI 有效载荷时,我们发现了与 Squid 最新版本的 ESI 解析相关的两个分布式拒绝服务攻击错误。这两个问题是空指针引用导致的错误,这将导致 Squid 服务崩溃。这两个漏洞的编号分别为 CVE-2018-1000024和 CVE-2018-1000027。以下两个公告详细说明了易受攻击的版本:

· http://www.squid-cache.org/Advisories/SQUID-2018_1.txt

· http://www.squid-cache.org/Advisories/SQUID-2018_2.txt

披露时间线:

· 2017年12月13日报告

· 2017年12月14日告知收到

· 2018年1月18日修复漏洞

· 2018年1月21日发布公告

下面是一个 ESI 的 include 运算对象可用于提取 cookies 的有效载荷:

ESI  的一些实现允许你指定要提取哪个 cookie; Squid 不提供这一功能,你必须一次提取出所有 cookie。

Varnish Cache

Varnish 实现的 ESI 在安全性方面相当可靠。ESI 的 include 指令只能对 VCL (Varnish Configuration Language)定义的上游服务器执行。这意味着 ESI 的 include 指令不能导致对任意主机的 SSRF。所有 SSRF 将被重定向到上游服务器,缓解了大多数 SSRF 攻击通常引起的问题。在本文发布时,在 Varnish Cache 中还没有实现 ESI vars。规范文档中有 vars 和 cookie 访问的实现计划。

在通过 Varnish 执行 ESI 时需要注意的一点是,默认情况下,如果 HTTP 响应的第一个非 nil 字符是小于号

71598ecbb3465cfaa7d3c8f9a8bffd7a.png

在 Varnish Cache 中处理二进制数据的 ESI 标记

禁用此功能后,用户可以使用文件上传功能(例如配置文件图片功能)并向上传的数据中添加 ESI 标记。然后,它们可以请求服务器返回内容,从而导致 ESI 注入。

另外,在查看 Varnish Cache 中的 ESI 实现时,我们发现在 src 属性中 ESI 的 include 指令没有转义回车符和换行符(CRLF)字符。这允许攻击者向 ESI 的 include 指令中注入 HTTP 标头,从而导致产生完整性良好的 HTTP 响应分割漏洞的奇怪变种。攻击者可以注入以下 ESI 有效载荷来生成一个带有两个额外 HTTP 头的 SSRF,X-Forwarded-For 和 JunkHeader:

GET / HTTP/1.1 Get / http / 1.1

User-Agent: curl/7.57.0 User-agent: curl / 7.57.0

Accept: */* * / *

Host: anything.com

X-Forwarded-For: 127.0.0.1 X-forded-for: 127.0.0.0.1

JunkHeader: JunkValue 1.1.1

X-Forwarded-For: 209.44.103.130 X-forded-for: 209.44.103.130

X-Varnish: 120

披露时间线:ESI  的 include 指令的请求看起来像这样:

· 2018年1月25日报告

· 2018年10月26日告知已收到

· 2018年2月13日修复漏洞

Fastly

Fastly 使用了大量自定义的 Varnish 后端,这意味着前面的大部分章节也适用于这一个供应商。仅有的两个区别是 ESI 的include 指令中的上游服务器不需要 Fastly 的 surrogate-control HTTP 头来解析 ESI 内容。此外,CRLF 注入似乎没有影响到 Fastly。

Akamai ESI 测试服务器(ETS)

Akamai 在 ESI 规范的开发中扮演了重要角色(作为作者和编辑)。这可以从它们的 ESI 实现中提供的大量特性以及它们提供的关于 ESI 的极其详细的文档中看到。显然,我们希望测试它们的 ESI 实现。2017年底,我们联系了 Akamai 的安全负责人,亲自提到了我们正在进行的 ESI 注入研究。由于 Akamai 是一个付费的服务提供商,我们要求获得一个生产环境级的测试镜像,在那里我们可以执行各种与 ESI  相关的测试,但我们的好心被拒绝了。由于我们没有得到 ESI 实例用于研究目的,所以我们尝试获得预售试用,但从未收到他们销售团队的回复。

我们最终决定对他们公开的 Docker 镜像进行测试。这个 Docker 镜像包含一个带有自定义模块—— mod_ESI.so  的 Apache HTTP 服务器。所以,此模块是其 ESI 实现的20mb ELF 32位编译版本。值得庆幸的是,由于前面提到的文档非常详细,所以没有必要使用逆向工程对这个 so 库进行逆向。由于这只是一个测试镜像,我们的发现可能不代表 Akamai 在生产环境中的实例。我们被告知,在生产环境中,ESI 在默认情况下是禁用的,并且已经设置了一些缓解控制,包括 SSRF 保护(主机白名单和其他缓解措施)和可选的 WAF。

也就是说,Akamai ETS (ESI Test Server)似乎容易受到上述所有场景的攻击(SSRF、 HTTPOnly 绕过、 XSS 过滤器绕过)。

要使用 ESI 的 include 指令提取 cookie,可以使用下面的 HTTP cookie 字典按名称引用特定的 cookie:

Akamai ETS 还提供了一系列有趣的特性,例如 ESI 调试模式。该模式通过  运算对象启用,当激活该模式时,它将向 HTTP 响应中添加大量调试信息,例如原始文件(在代理服务器上可以看到而不是应用服务器)和所有环境变量。

还可以通过向 dca 参数指定 XSLT 值来添加基于 XSLT 的 ESI include 指令。下面的 include 指令将导致 HTTP 代理项请求 XML 和 XSLT 文件。然后使用 XSLT 文件过滤 XML 文件。此 XML 文件可用于执行 XML 外部实体(XXE)攻击。这允许攻击者执行 SSRF 攻击,但这并不十分有用,因为这必须通过 ESI include 执行,而 ESI include 本身就是 SSRF 向量。由于基础库(Xalan)不支持外部 DTD,因此不解析外部 DTD。这意味着我们不能提取本地文件。

XSLT 文件:

]>

&xxe;

然而,由于我们可以使用 XML 实体,所以,出现在十年前的 Billon-Laugh 攻击是有可能的。这种攻击将递归地引用实体,导致挂起和内存耗尽,从而导致分布式拒绝服务攻击。我们在使用 Akamai ETS Docker 镜像在本地执行了攻击,在一台有32gb 内存的机器上服务停止了几秒钟。下面的 XSLT 文件可用于执行内存耗尽攻击:

]>

&lol9;

NodeJS 的 ESI

为了支持 ESI 标签,开发了一些 node.js 模块。它们可以用作中间件、模仿代理项或在源代码中内联。这个库对 ESI 规范的实现相当多,支持 include指令、变量 和 cookie。

要使用 ESI 的 include 指令提取 cookie,可以使用 HTTP_COOKIE 变量提取每个 cookie:

NodeJS 的 nodESI 

此模块只支持 ESI 的 include 指令,不支持 ESI 变量。当执行 ESI 注入时,该模块的维护人员实现了一个主机白名单机制,并在模块的文档中添加了一个安全章节。

其他供应商

我们没有对上述之外的任何其他供应商进行测试; 这不是对任何其他供应商关于其实现 ESI 安全性的产品的认可或批评。

784f70a0255e2a69b7fb101cd56a66c1.png如何检测 ESI 注入攻击

b22fdc109fb0e377deae04fdbcdec6e3.png

有些代理将要求 ESI 处理在 Surrogate-Control  HTTP 报头中发出的信号,从而允许简单的检测。此标头用于向上游服务器指示 ESI 标记可以出现在响应中,并且应该按照这种方式对它们进行解析。如果你观察到如下 HTTP 头响应: Surrogate-Control: content="ESI/1.0” ,那么你可能正在处理支持 ESI  的基础结构。

但是,大多数代理和负载均衡器会在将该报头发送到客户机之前从上游服务器中进行移除。有些代理也不需要任何 Surrogate-Control  头。因此,这不是确定 ESI 使用的确切方法。由于 ESI 实现中的特性选择种类繁多,因此不能执行任何唯一的测试方法来测试 ESI 注入。人们必须测试各种有效载荷并观察副作用,以正确识别 ESI 可注入的端点。例如,可以使用 ESI 的 include 指令对攻击者控制的服务器执行 SSRF,但是有些实现会要求主机必须在白名单内。

注:本文参考自:gosecure.net

c6f84575b92107e38611dfbdeeaa9790.png

eb9e375d6f6529e7c358fe66465469a2.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openstack nova-network 的小bug的排错经历

环境是 nova-network vmwareflatdhcp错误表现为 开出来的虚拟机有一定几率获取不到dhcp地址,手工赋予ip则正常,用flat模式注入的ip正常,下面是排错过程1首先找网络防火墙已经把 dnsmasq对应的端口已经打开抓包结果:可以看到虚拟机…

anaconda base环境_anaconda中安装packages:pip还是conda install?

conda install我就不说了,这都不会别学了就。Using command:$ which -a pip, the terminal will return:This indicates two different pip path to install packages[1].在tf23环境中pip install在base环境中pip install在windows下powershell内,进入到…

【风马一族_xml】xmlp之dtd1

什么是XML约束?在xml技术里,可以编写一个文档来约束一个xml文档的写法,这称之为xml约束 2. 为什么要使用xml约束? 参看提示栏 3. xml约束的作用? 约束xml的写法对xml进行校验4. 常见的xml约束技术 xml dtdxml Schema…

java ssm框架 缓存_SSM框架之MyBatis3专题4:查询缓存

查询缓存的使用,主要是为了提高查询访问速度。将用户对同一数据的重复查询过程简化,不再每次均从数据库中查询获取结果数据,从而提高访问速度。MyBatis的查询缓存机制,根据缓存区的作用域(声明周期)可划分为两种:一级查…

matplotlib画图_漂亮,超详细的matplotlib画图基础

来自 | 逐梦erhttps://zhumenger.blog.csdn.net/article/details/106530281本文仅作技术交流,如有侵权,请联系后台删除。数据可视化非常重要,因为错误或不充分的数据表示方法可能会毁掉原本很出色的数据分析工作。matplotlib 库是专门用于开发…

android recycleview长按多选_UI设计中Android和IOS设计差异总结

由于设计师、产品经理使用的移动设备大部分是iPhone,所以在做设计时,容易忽略Android和iOS的差异,按照iOS的规范进行设计,两端只做一套。只做一套的会存在两个问题:1、安卓用户的使用习惯不太适应iOS的设计&#xff0c…

自定义动画属性java_创建酷炫动画效果的10个JavaScript库

原标题:创建酷炫动画效果的10个JavaScript库1) Dynamics.jsDynamics.js是设计基于物理规律的动画的重要Java库。它可以赋予生命给所有包含CSS 和SVG属性的DOM(文本对象模型)元素,换句话说,Dynamics.js适用于所有Java对象以及一系列其它的元素…

php xlsx里插入图片_常见的 PHP 面试题和答案分享

如何直接将输出显示给浏览器&#xff1f;将输出直接显示给浏览器&#xff0c;我们必须使用特殊标记 <&#xff1f;and&#xff1f;>。PHP 是否支持多重继承&#xff1f;PHP 只支持单继承。PHP 的类使用关键字 extends 继承另一个类获取图片属性&#xff08;size, width, …

pandas concat_pandas-数据合并-concat(最全参数解释,含代码和实例)

pandas中的concat的功能&#xff1a;假设你现在需要将多个数据合并&#xff0c;前提是&#xff1a;这几个文件列名都一致&#xff0c;也就是说这几个文件格式完全一样&#xff0c;只是数据不太一样&#xff0c;类似于合并多个文件这种&#xff0c;实际数据分析中也会遇到这种情…

java中的de是什么_【转】java中main函数解析

源地址&#xff1a;http://www.cnblogs.com/xwdreamer/archive/2012/04/09/2438845.html从写java至今&#xff0c;写的最多的可能就是主函数public static void main(String[] args) {}但是以前一直都没有问自己&#xff0c;为什么要这么写&#xff0c;因为在c语言中就没有这样…

JAVA多线程(一)线程安全问题产生的原因

JAVA线程内存与主存间映射示意图Java内存模型中规定了所有的变量都存储在主内存中&#xff0c;每条线程还有自己的工作内存&#xff0c;线程的工作内存中保存了该线程使用的变量到主内存副本拷贝&#xff0c;线程对变量的所有操作&#xff08;读取、赋值&#xff09;都必须在工…

两顶点的路径长度为k_计算两个顶点之间的所有可能路径

两顶点的路径长度为kWhat to Learn? 学什么&#xff1f; How to count all possible paths between two vertices? 如何计算两个顶点之间的所有可能路径&#xff1f; In the graph there are many alternative paths from vertex 0 to vertex 4 在图中&#xff0c;有许多从…

covariance matrix r语言_时间序列分析|ARIMAX模型分步骤详解和R中实践

这是关于时间序列的第N篇文章&#xff0c;本文将介绍ARIMAX模型&#xff0c;简单来说就是在ARIMA的基础上增加一个外生变量。ARIMAX和ARIMA相比在理论上没有太多新的内容&#xff0c;所以本文直接介绍在R里怎么一步一步跑ARIMAX。在阅读这篇文章前&#xff0c;需要对ARIMA有一定…

linux系统编程之文件与I/O(六):fcntl 函数与文件锁

2013-05-14 11:26 8290人阅读 评论(2) 收藏 举报分类&#xff1a;linux系统编程&#xff08;19&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 一、fcntl函数 功能&#xff1a;操纵文件描述符&#xff0c;改变已打开的文件的属性 int…

bandizip最后一个无广告版本_如果非要选择一款压缩软件的话——Bandizip

全世界只有不到0.00~1 % 的人关注了我们得到你的关注是小帮的幸运压缩解压软件是电脑一个必备软甲&#xff0c;前面的文章介绍了一款开源小巧无广告的压缩解压软件windows工具软件选择之压缩软件——7-Zip&#xff0c;如果有人用不惯的话可以试试今天的这款。Bandizip 是一款来…

[MVC学习笔记]1.项目结构搭建及单个类在各个层次中的实现

新人刚开始学习ASP.NET MVC&#xff0c;若有不足之处希望能得到您的指点&#xff0c;不胜感激&#xff01; 先来一张项目的层级结构图: Model&#xff1a;模型层&#xff0c;主要是各种类型、枚举以及ORM框架&#xff0c;框架完成数据库和实体类的映射。项目中选用了微软的开源…

mybatisplus代码生成器_想做时间管理大师?你可以试试Mybatis Plus代码生成器

1. 前言对于写Crud的老司机来说时间非常宝贵&#xff0c;一些样板代码写不但费时费力&#xff0c;而且枯燥无味。经常有小伙伴问我&#xff0c;胖哥你怎么天天那么有时间去搞新东西&#xff0c;透露一下秘诀呗。好吧&#xff0c;今天就把Mybatis-plus的代码生成器分享出来&…

c++ websocket客户端_websocket使用

websocket使用一、介绍在项目开发过程中&#xff0c;很多时候&#xff0c;我们不可避免的需要实现的一个功能&#xff1a; 服务端实时发送信息给客户端。比如实时公告、实时订单通知、实时报警推送等等&#xff0c;登录后的客户端需要知道与它相关的实时信息&#xff0c;以便进…

在cordova中使用HTML5的多文件上传

2019独角兽企业重金招聘Python工程师标准>>> 我们先看看linkface给开放的接口&#xff1a; 字段类型必需描述api_idstring是API 账户api_secretstring是API 密钥selfie_filefile见下方注释需上传的图片文件 1&#xff0c;上传本地图片进行检测时选取此参数selfie_ur…