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

Elasticsearch:如何使用 Elastic 检测恶意浏览器扩展

作者:来着 Elastic Aaron Jewitt

当你的 CISO 询问你的任何工作站上是否安装过特定的浏览器扩展时,你多快能得到正确答案?恶意浏览器扩展是一个重大威胁,许多组织无法管理或检测。这篇博文探讨了 Elastic Infosec 团队如何使用 osquery 和 Elastic Stack 创建所有浏览器扩展和检测规则的实时清单,以及如何在工作站有已知的受损浏览器扩展时通知团队。该解决方案完全使用 osquery、Elastic Defend 集成和 Elastic Stack 中的 SIEM 功能构建。

针对浏览器扩展的威胁行为者

威胁行为者越来越关注针对浏览器扩展程序来窃取信息或危害用户,甚至一些威胁行为者直接针对合法扩展程序的开发人员,目的是添加恶意代码。

有了足够的权限,浏览器扩展程序就可以查看或更改你使用浏览器访问的任何网站上的任何信息,并收集传递给网站的敏感信息,例如用户名、密码或银行帐户信息。扩展程序可以访问并窃取任何网站存储的身份验证令牌。他们甚至可以改变网站内容,通过社会工程手段诱使用户下载恶意软件到他们的工作站,比如改变链接的目的地。

业务挑战

管理企业中的浏览器扩展带来了一些复杂的挑战。

  • 扩展程序是根据浏览器内的配置文件进行安装的。
  • 工作站上的每个用户帐户可以在每个浏览器中拥有多个不同的配置文件,例如个人配置文件和工作配置文件。
  • 通常,工作站会具有五个或更多不同的用户配置文件 — — 每个配置文件都有自己安装的一组扩展。

有一些选项,例如托管浏览器可以通过创建扩展的允许或阻止列表来控制公司配置文件的安装扩展,但这些解决方案不会管理这些工作站上的非公司配置文件。如果用户从个人资料登录工作系统,公司工作站上的个人浏览器扩展仍然会给你的公司带来风险。另一个风险情况是个人扩展程序可能会动态更改点击链接的目的地,导致用户将恶意文件下载到其工作系统中。

在 Kibana 中部署和管理 osquery

osquery 是一个开源代理,适用于几乎所有现代操作系统(OS)。它将每个操作系统视为一个关系数据库,其中包含表,你可以查询这些表来收集有关系统当前状态的信息。你可以查询模式中的 200 多个表以获取信息,例如正在运行的进程;已安装的浏览器扩展; Python 库;装载了docker容器;加载内核模块;打开网络连接;连接的 USB 设备;等等。

在 Elastic,我们使用自己的 XDR 功能保护所有工作站,其中包括将 Elastic Agent 部署到所有工作站以进行分布式保护和响应。 Elastic Security 的一大优势是能够使用 Kibana 中的 Osquery Manager 集成轻松地将 osquery 部署到你的端点并进行管理。 osquery 集成包含在基本许可证中 —— 在你的代理群中部署它无需额外的许可费用。

更多有关 osquery 的阅读,请参阅文章:

  • Security:osquery 介绍

  • Elasticsearch:使用 osquery 和 Elastic Stack 来监控你的端点

使用 osquery 和 Elastic 的优势

Elastic Defend 和其他端点检测和响应 (EDR) 代理可以从工作站传输实时进程、网络和文件日志。但是这些审计日志无法告诉你有关操作系统状态的所有信息,例如已安装的浏览器扩展。这就是 osquery 的用武之地。它让我们捕获工作站当前状态的快照,以便我们知道用户拥有哪些 Chrome 扩展程序。

只需在 Kibana 中单击几下,你就可以将 osquery 部署到所有工作站,并直接在 Elastic Stack 中管理和查看查询 - 使用 Kibana 管理 osquery 时不需要额外的基础设施。将 osquery 与 Elastic 结合使用的另一个优点是,所有查询的结果都会立即被纳入 Elasticsearch 索引中,并可用于各种用例。将结果导入到你的 Elastic Stack 中还可以为你提供查询的历史时间线,你可以使用该时间线查看系统在一段时间内硬件和软件发生的更改。

有关在 Elastic 中使用 osquery 的更多信息,请查看 osquery 文档指南。

在 Elastic 中使用 osquery

在 osquery 中,有两种方式运行查询 - 立即作为实时查询或作为 osquery 所称的查询包的定期调度的查询组的一部分。

实时查询 - Live query

实时查询将针对一个或多个主机运行单个查询。实时查询是在测试期间构建和优化查询或在调查期间寻找特定指标的好方法。在 Elastic 中选择运行实时查询的主机时,你可以单独选择主机、按队列策略选择所有主机或按操作系统选择。如果在运行实时查询时代理处于离线状态,则如果代理在接下来的 60 分钟内上线,它将保持排队状态;否则将被清除。 Elastic 版本的 osquery 的一个功能是保存的查询。此功能可以轻松地预先配置常用的复杂查询,然后其他团队成员可以使用这些查询。

查询包 - Query pack

查询包是计划以不同间隔运行的预配置查询的集合。包中的每个查询都可以指定它将在哪个操作系统平台上运行,因此单个包可以在具有多个操作系统的策略上安全地使用。查询包可以作为 .json 文件导出和导入,以便你在 Kibana 中快速添加包。 osqery 提供了一些示例包供你使用,或者你可以尝试我们用来清点浏览器扩展的 browser_monitoring 包。

使用 osquery 创建所有扩展的清单

Elastic Infosec 团队已将 browser_monitoring 包配置为我们所有工作站上每六小时运行一次,以创建所有浏览器扩展的清单。我们每六个小时运行一次查询,因为 Elastic 是一家全球分布的公司,我们无法预测用户的工作时间。

browser_monitoring 查询包

由于多个用户配置文件带来的复杂性,收集浏览器扩展信息的查询需要 JOIN 运算符将 users 表连接到扩展表。 JOIN 运算符将使用两个表中都存在的公共字段将两个表组合在一起。在这种情况下,它是用户 ID uid 字段。

SELECT * FROM users JOIN chrome_extensions USING (uid)

还可以直接在 osquery UI 中查看包查询的结果,并通过链接在 Kibana Discover 或 Lens 中打开每个查询的结果。

browser_monitoring 结果视图

所有查询的结果都直接存储到 logs-osquery_manager.result* 索引模式中。可以使用 action.id 字段找到计划包查询的结果。对于打包结果,该字段遵循 pack_{pack_name}_{query_name} 的命名约定。我们正在使用一个名为 browser-monitoring 的包和一个名为 chrome_extensions 的查询。要查看此查询的结果,你可以查询action_id:“pack_browser-monitoring_chrome_extensions”。

在 Discover 中查看 osquery 的结果时,你将看到 osquery 模式表中的每个字段都使用 osquery.* 字段名进行索引。在查看有关 Chrome 扩展程序的信息时,我们最常用的字段是 osquery.identifier、osquery.name、osquery.permissions、osquery.profile 和 osquery.version。

示例查询结果

以下是 chrome_extension 查询响应中可用字段的完整列表:

  • osquery.identifier 是每个扩展的唯一标识符。通过此标识符,你可以在 Google Chrome 网上应用店中找到该扩展程序,或者使用 Secure Annex 或 crxaminer.tech 等服务查找该扩展程序的信誉分数。
  • osquery.name 是 Chrome 网上应用店和浏览器中显示的扩展程序的名称。
  • osquery.profile 是安装该扩展程序的 Google Chrome 配置文件。用户在单用户帐户中拥有多个不同的 Chrome 配置文件是很常见的。
  • osquery.permissions 是授予扩展的权限。该字段可用于过滤被授予危险权限的扩展,例如查看或修改每个网站的请求的权限。密切关注任何具有权限的扩展,例如 https://*/* ,它授予扩展对你访问的每个 https 网站的访问权限。
  • osquery.version 是扩展的安装版本。在某些情况下,扩展程序可能有一个你想要删除的受损版本。
  • osquery.update_url 是扩展用来检查任何更新的 url。如果此值不是标准更新路径 https://clients2.google.com/service/update2/crx,则表示扩展已被 “sideloaded - 侧载” 或以标准网络商店以外的某种方式安装,应进行调查。

另一个非常重要的 osquery 表是 chrome_extension_content_scripts。该表包含有关扩展所使用的每个 javascript 文件的信息。如果发现主机上存在受到感染的扩展,则可以使用该表中的 osquery.path、osquery.match 和 osquery.script 字段来查找扩展运行的每个脚本的完整路径。利用这些信息,你可以使用 Elastic Defend 的响应操作功能下载这些文件进行离线分析。

创建不良扩展的检测规则

现在你已拥有所有浏览器扩展的实时清单,你可以构建检测。最直接的检测方法是针对已知的坏扩展进行检测。已知的不良扩展列表可能来自包含已知标识符和版本的威胁情报(threat intelligence)报告。在这个例子中,我们将使用最近报道的 Cyber​​haven 扩展入侵活动的威胁情报。报告底部是指向 IOC 集合的链接,其中包含已知恶意扩展的名称、ID 和版本。

NameIDVersion
VPNCitynnpnnpemnckcfdebeekibpiijlicmpom2.0.1
Parrot Talkskkodiihpgodmdankclfibbiphjkfdenh1.16.2
Uvoiceoaikpkmjciadfpddlpjjdapglcihgdle1.0.12
Internxt VPNdpggmcodlahmljkhlmpgpdcffdaoccni1.1.1
Bookmark Favicon Changeracmfnomgphggonodopogfbmkneepfgnh4.00
Castorusmnhffkhmpnefgklngfmlndmkimimbphc4.40
Wayin AIcedgndijpacnfbdggppddacngjfdkaca0.0.11
Search Copilot AI Assistant for Chromebbdnohkpnbkdkmnkddobeafboooinpla1.0.1
VidHelper - Video Downloaderegmennebgadmncfjafcemlecimkepcle2.2.7
AI Assistant - ChatGPT and Gemini for Chromebibjgkidgpfbblifamdlkdlhgihmfohh0.1.3
TinaMind - The GPT-4o-powered AI Assistant!befflofjcniongenjmbkgkoljhgliihe2.13.0
Bard AI chatpkgciiiancapdlpcbppfkmeaieppikkk1.3.7
Reader Modellimhhconnjiflfimocjggfjdlmlhblm1.5.7
Primus (prev. PADO)oeiomhmbaapihbilkfkhmlajkeegnjhe3.18.0
Tackker - online keylogger toolekpkdmohpdnebfedjjfklhpefgpgaaji1.3
AI Shop Buddyepikoohpebngmakjinphfiagogjcnddm2.7.3
Sort by Oldestmiglaibdlgminlepgeifekifakochlka1.4.5
Rewards Search Automatoreanofdhdfbcalhflpbdipkjjkoimeeod1.4.9
Earny - Up to 20% Cash Backogbhbgkiojdollpjbhbamafmedkeockb1.8.1
ChatGPT Assistant - Smart Searchbgejafhieobnfpjlpcjjggoboebonfcg1.1.1
Keyboard History Recorderigbodamhgjohafcenbcljfegbipdfjpk2.3
Email Huntermbindhfolmpijhodmgkloeeppmkhpmhc1.44
Visual Effects for Google Meethodiladlefdpcbemnbbcpclbmknkiaem3.1.3
Cyberhaven security extension V3pajkjnmeojmbapicmbpliphjmcekeaac24.10.4
GraphQL Network Inspectorndlbedplllcgconngcnfmkadhokfaaln2.22.6
GPT 4 Summary with OpenAIepdjhgbipjpbbhoccdeipghoihibnfja1.4
Vidnoz Flex - Video recorder & Video sharecplhlgabfijoiabgkigdafklbhhdkahj1.0.161
YesCaptcha assistantjiofmdifioeejeilfkpegipdjiopiekl1.1.61
Proxy SwitchyOmega (V3)hihblcmlaaademjlakdpicchbjnnnkbo3.0.2
ChatGPT Applbneaaedflankmgmfbmaplggbmjjmbae1.3.8
Web Mirroreaijffijbobmnonfhilihbejadplhddo2.4
Hi AIhmiaoahjllhfgebflooeeefeiafpkfde1.0.0

使用此 IOC 列表,有两种不同的方法来构建检测。最简单的方法是使用这些 ID 和版本值来构建单个大型 Elasticsearch 查询,该查询查看 osquery 数据中任何这些扩展标识符和版本,并使用 OR 运算符链接在一起。例如:

action_id: pack_browser-monitoring_chrome_extensions AND ((osquery.identifier: "nnpnnpemnckcfdebeekibpiijlicmpom" AND osquery.version:	"2.0.1") 
OR(osquery.identifier: "kkodiihpgodmdankclfibbiphjkfdenh" AND osquery.version:	"1.16.2")  
OR(osquery.identifier: "oaikpkmjciadfpddlpjjdapglcihgdle" AND osquery.version:	"1.0.12")
)

如果你使用我们的其中一种威胁情报集成(threat intelligence integrations)将威胁情报源提取到你的 Elastic Stack,则可以使用指标匹配规则类型(indicator match rule type)创建此规则的更动态版本。指标匹配规则比较两个不同索引模式中的字段,当这些字段匹配时会触发警报。如果你的威胁源支持 Google Chrome 扩展程序 ID 和版本,则可以创建一个指示器匹配规则,当已安装的 Chrome 扩展程序 ID 和版本与已知的恶意扩展程序匹配时,该规则会向你发出警报。

以下是指标匹配规则的示例配置。指标索引字段名称将根据所使用的威胁情报平台而改变。

指标匹配规则配置示例

这种方法的优点是,每次发布或更新新的已知不良扩展列表时,不需要手动更新检测规则。一旦新的指标添加到你的威胁情报索引中,你将立即收到警报。

尝试一下

威胁行为者将继续使用 Chrome 扩展程序来窃取有价值的信息和目标系统。如果你无法查看工作站上安装的扩展程序,则无法保护用户免受此攻击媒介的侵害。使用 osquery 和 Elastic,你可以管理和降低企业的整体风险,并通过浏览器扩展的可见性和警报,而无需额外的许可费用。

你可以免费试用 Elastic Cloud 14 天,亲自尝试一下。

要查看浏览器扩展程序如何在实际攻击中使用的例子,请查看《超越恐惧:解构 Elastic Security Labs 的 BANSHEE 信息窃取程序》。

本文中描述的任何特性或功能的发布和时间均由 Elastic 自行决定。任何当前不可用的特性或功能可能无法按时交付或根本无法交付。

原文:How to detect malicious browser extensions using Elastic | Elastic Blog

相关文章:

Elasticsearch:如何使用 Elastic 检测恶意浏览器扩展

作者:来着 Elastic Aaron Jewitt 当你的 CISO 询问你的任何工作站上是否安装过特定的浏览器扩展时,你多快能得到正确答案?恶意浏览器扩展是一个重大威胁,许多组织无法管理或检测。这篇博文探讨了 Elastic Infosec 团队如何使用 os…...

Oracle CDB自动处理表空间不足脚本

之前我曾经发过一个自动处理表空间的脚本,可以通过定时任务自动处理表空间不足的问题;但是之前那个脚本没有涵盖CDB模式下的PDB,这里将脚本做了一下更新,可以处理CDB模式下多PDB的表空间问题。 传统模式的脚本请参考这个链接 Or…...

java-list深入理解(流程图)

List源码学习: 此篇文章使用流程图和源码方式,理解List的源码,方便记忆 核心逻辑流程图: #mermaid-svg-BBrPrDuqUdLMtHvj {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-BBrPrDuqUdLMtHvj .error-icon{fill:#…...

Vue 中的 keep-alive 组件是什么?

Vue 中的 keep-alive 组件 keep-alive 是 Vue.js 提供的一个内置组件,用于在组件切换时缓存组件的状态。它可以有效提高用户体验,特别是在需要频繁切换视图的场景中,例如在 SPA(单页面应用)中。 目录 什么是 keep-alive如何使用 keep-alive属性介绍实际示例注意事项总结…...

单元测试的入门实践与应用

单元测试的目的是验证代码中最小的可测试单元(通常为函数或方法)是否按预期运行。它应当独立于系统的其他部分,并专注于特定的功能。 在软件开发中,单元测试是确保代码质量与可维护性的核心环节。优秀的单元测试不仅能帮助开发者…...

【大模型】硅基流动对接DeepSeek使用详解

目录 一、前言 二、硅基流动介绍 2.1 硅基流动平台介绍 2.1.1 平台是做什么的 2.2 主要特点与功能 2.2.1 适用场景 三、硅基流动快速使用 3.1 账户注册 3.2 token获取 3.2.1 获取token技巧 四、Cherry-Studio对接DeepSeek 4.1 获取 Cherry-Studio 4.2 Cherry-Stud…...

[Windows] PDF补丁丁v1.1.0.4627绿色版

[Windows] PDF补丁丁 链接:https://pan.xunlei.com/s/VOIdp50MV2BkOrFott_SCev1A1?pwdvbw4# PDFPatcher 是一款专门用于编辑 PDF 文件的软件,其主要功能包括添加、删除、修改、替换和提取 PDF 文件中的文本、图像、页面等内容,以及支持密码…...

Oracle 变更redo log文件位置

更改Oracle数据库的Redo log文件位置,可以按照以下步骤操作。 1.查询当前Redo log文件信息 select * from v$log; select * from v$logfile;通过查询结果可知Redo log文件放在/oradata/redofile 目录下。 2.拷贝redo log文件到新的位置/Data/redolog $cd /orada…...

使用Redis实现业务信息缓存(缓存详解,缓存更新策略,缓存三大问题)

一、什么是缓存? 缓存是一种高效的数据存储方式,它通过将数据保存在内存中来提供快速的读写访问。这种机制特别适用于需要高速数据访问的应用场景,如网站、应用程序和服务。在处理大量数据和高并发请求时, 缓存能显著提高性能和用户体验。 Redis就是一款常用的缓存中间件。…...

已验证正常,Java输入字符串生成PDF文件

Java输入字符串生成PDF文件过程&#xff1a; 在Java开发中&#xff0c;如何将字符串转换为 PDF 是一个常见的需求。网上找了很多例子都无法生成&#xff0c;经过多次尝试&#xff0c;终于实现了&#xff0c;特此记录一下。 1、引入pom.xml 添加所需的依赖 <dependency>&…...

android手机安装deepseek-r1:1.5b

序 本文主要展示一下如何在android手机上安装deepseek-r1:1.5b 步骤 安装termux 到https://termux.dev/cn/index.html去下载 然后执行termux-setup-storage以获取手机存储权限 安装构建依赖 pkg install git cmake golang下载ollama git clone --depth 1 https://gitee.…...

51单片机俄罗斯方块清屏函数

/************************************************************************************************************** * 名称&#xff1a;LED_Clr * 功能&#xff1a;清屏 * 参数&#xff1a;NULL * 返回&#xff1a;NULL * 备注&#xff1a;temp数组为动态显示数据&#xff…...

PLSQL: 存储过程,用户自定义函数[oracle]

注意: raise notice是高斯的输出语句; DBMS_OUT_PUT.PUT_LINE是oracle的输出语句 存储过程 Stored Procedure 存储过程可以封装数据访问逻辑&#xff0c;使得应用程序可以通过调用存储过程来执行这些逻辑&#xff0c;而不是直接执行SQL语句。这有助于提高代码的可重用性、可…...

深度学习-医学影像诊断

以下以使用深度学习进行医学影像&#xff08;如 X 光片&#xff09;的肺炎诊断为例&#xff0c;为你展示基于 PyTorch 框架的代码实现。我们将构建一个简单的卷积神经网络&#xff08;CNN&#xff09;模型&#xff0c;使用公开的肺炎 X 光影像数据集进行训练和评估。 1. 安装必…...

备战蓝桥杯:双指针(滑动窗口)算法之逛花展

P1638 逛画展 - 洛谷 | 计算机科学教育新生态 这道题我们只要用一个kind和一个mp[N]的数组就能解决了 我们的解法1就是暴力枚举&#xff0c;先固定2&#xff0c;从2开始找连续的满足所有种类的最短的子数组&#xff0c;然后固定5&#xff0c;3&#xff0c;1&#xff0c;3&…...

Linux如何设置软件开机启动呢?

有很多软件&#xff0c;我们安装完之后&#xff0c;服务器一旦重启&#xff0c;软件也需要我们手动再次启动&#xff0c;有很多的软件我们不想手动重启&#xff0c;例如Redis、Mysql、MQ等&#xff0c;那我们怎么配置软件跟着服务器也一起启动呢&#xff0c;今天就给大家带来软…...

Vue(3)

一.生命周期及其四个阶段 Vue生命周期&#xff1a;一个Vue实例从创建到销毁的整个过程 生命周期四个阶段&#xff1a;①创建②挂载③更新④销毁 <body><div id"app"><h3>{{ title }}</h3><div><button click"count--"&…...

11vue3实战-----封装缓存工具

11vue3实战-----封装缓存工具 1.背景2.pinia的持久化思路3.以localStorage为例解决问题4.封装缓存工具 1.背景 在上一章节&#xff0c;实现登录功能时候&#xff0c;当账号密码正确&#xff0c;身份验证成功之后&#xff0c;把用户信息保存起来&#xff0c;是用的pinia。然而p…...

第16章 Single Thread Execution设计模式(Java高并发编程详解:多线程与系统设计)

简单来说&#xff0c; Single Thread Execution就是采用排他式的操作保证在同一时刻只能有一个线程访问共享资源。 1.机场过安检 1.1非线程安全 先模拟一个非线程安全的安检口类&#xff0c;旅客(线程)分别手持登机牌和身份证接受工作人员的检查&#xff0c;示例代码如所示。…...

MySQL 8.0.41 终端修改root密码

1.在 MySQL 命令行中&#xff0c;运行以下命令修改密码 ALTER USER rootlocalhost IDENTIFIED BY new_password; 其中&#xff0c;new_password替换为你想要设置的新密码 2.退出 MySQL终端&#xff0c;重新打开&#xff0c;使用新密码进入&#xff0c;修改成功...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...