Re: [讨论] PHP是个漏洞多且不安全的后端语言?

楼主: GALINE (天真可爱CQD)   2020-05-16 18:17:28
※ 引述《red0whale (red whale)》之铭言:
: 昨天我的数据库老师说
: PHP是一个漏洞相当多、非常不安全
: 而且是外面业界鲜少在使用的后端程式语言
: 他还说PHP只是给学生在用的程式语言
你老师的说法虽然有不少...误会,不过反正前面打脸也满多了
我觉得可以认真思考一下那些有沾到边的部分
: 而他建议我们做网页后端最好使用像C#或Java之类的需要编译过后才能使用的“编译语言
: ”
: 而非使用像PHP这种“直译语言”
: 原因之一在于PHP是以明文储存程式码
: 在外面业界如果使用明文丢后端程式语言给其他人,早就造成安全上的漏洞了
: 所以非常不建议使用PHP作为网页后端的程式语言
先假装不知道可以用 java decompiler 或 dotPeek 反组译程式码这件事
这个论点看起来像是“程式码被看光光很危险”(某些时候这是事实)
延伸出来的下一个问题是“什么情况下‘别人’会看到我写的 PHP 程式码?”
我比较常听说这两种状况
- 网页服务器明明该执行 PHP 却没执行,把 PHP 当成文字档直接吐出来
- 程式本来该读让使用者下载的档案,却不知道为什么(笑)去读了 PHP 档案本身
- ex: 使用者在网址列输入 /download.php?file=download.php
前者属于服务器设定错误,不是 PHP 本身的包
但写 PHP 的人通常可以多做一层防护:
确保你的网页目录里面只有 index.php 这只 PHP
里面只做最小程度的初始化,没有其他逻辑
所有的逻辑都该放在网页目录之外
比较新的 PHP 框架都是这么干
- https://github.com/laravel/laravel/tree/master/public
- https://github.com/slimphp/Slim-Skeleton/tree/master/public
这样就算设定出包,外面的坏人也只能看到里面没什么料的 index.php
这题有个延伸注意事项:小心别让 .git 目录出现在网页目录内
不然不管你用哪种语言都会被人整包端走,出这种包的网站意外多...
动态下载这题,锅会是开发者要背
如果你需要让人动态下载档案,我一下想到这几种做法
- 档案名称做白名单检查,不在白名单内就不给下载
- 取档案的 key 不要直接就是档案名称,自己做一个对应表
还有,如果你是接案的乙方,结案时只想给能动的程式不想给原始码
PHP 确实不会是优先选择
: 另外,他也提及
: 用PHP连后端数据库是非常危险的
: 原因也是因为直译式的关系
: 如果用PHP的话,数据库的帐号密码之类的也很容易外露造成资安漏洞
这看起来像是上面的延伸:看到 code,不就知道数据库密码了
我的回答是:谁把数据库密码写死到 code 里面我就揍谁 =__=
程式逻辑应该从其他地方取得密码或 token 之类的机敏资讯
- 也许是环境变量(对 server 要有控制权)
- 也许是某个跟程式码分开管理的机敏资料档案(记得别放进网页 public 目录)
- 也许是专门的机敏资讯管理服务,ex: HashiCorp Vault、AWS Secrets Manager
- 个人或学生通常不会搞这么大,知道这件事可以复杂到有人靠这个赚钱就好
然后不要觉得编译过的语言就可以把密码写死在 code 里面
就算假装不知道可以用 java decompiler 或 dotPeek 反组译程式码
程式码没混淆的话有耐心的人用 hex editor 一样找得出来
另,数据库连线有问题时,PDO 喷出的错误讯息可能会包含机敏资讯
所以对外服务用的 server 应该要确保使用者不会看到错误讯息
例如:关掉 error_reporting;用 framework 的时候,关掉 debug 讯息
: 所以他说在外面业界几乎很少有人会使用像PHP这种直译式程式语言作为网页后端的程式
: 语言
: 也非常不建议使用PHP,因为它本身的漏洞实在太多,且相当不安全
: 不晓得各位有什么看法?
: 对于PHP不安全、漏洞多有没有什么能够补救的办法?
PHP 本身没有那么不安全,安全纪录不算特别差
但由于 PHP 的出身是开发者要自己处理跳脱问题的 HTML 样版引擎
而自己处理跳脱囉唆又麻烦又容易忘记(或根本不知道要处理跳脱问题)
所以 PHP 很容易引诱写程式的人写出不安全的网页程式
PHP 过去一些失败的设计也会加深这件事(有兴趣可以找找 Magic quote)
纵使现在 PHP 脱胎换骨了,许多旧的写法在现代依然能被使用
当你发现你正在写 HTML 跟 PHP 缠在一起的的程式,你应该觉得紧张害怕
然后深呼吸,平复情绪
接着花至少一个小时去看搜寻“PHP injection”能找到的每一篇网页
又或者,你应该用其他人写的样板引擎,例如 twig
(有一大堆人在 PHP 这套样版引擎里面写自己的样版引擎,这也是个成就...)
如果你看到眼前的教材是 HTML 跟 PHP 缠在一起的的程式
请记住,你工作时不该那样写 code,但那些东西做为教材(也许)是及格的
知道怎么飞双人座单引擎螺旋桨小飞机
跟能知道怎么飞承载数百人的双引擎喷射客机是两回事
但是每个广体喷射机驾驶都得从螺旋桨小飞机开始
再重申一次,如果看到有 code 把 PHP 跟 HTML ,或其他任何语言写在一起
就应该小心 injection 问题
不管是看到 PHP 组 HTML // <p><?=$foo?><p>
还是看到用 PHP 组 SQL // "select * from table where id={$id}"
或是看到用 PHP 组 javascript // <script>let a = <?=$a?>;</script>
都要让心里面有个红灯号亮着
: 顺带一提,我也有想过,像Facebook、Wikipedia 之类的大网站不也是使用PHP作为其中
: 一种程式语言吗?
: 虽然昨天也有跟老师讨论到这个
: 不过老师是跟我说,那些大网站使用PHP也只是用来做显示前端的一些部分
: 真正使用后端像是连数据库之类的根本不可能使用PHP来写
: 他说如果他们用PHP做后端的话是相当不安全、风险很高的作法
PHP 连数据库没什么稀奇...
对于大型服务,重点是整体服务架构,这群东西能不能放在一起打群架
程式语言只是众多抉择的其中一个
PHP 是不是“不好的选择”,要连需求跟整包架构一起看
回过头来讲一下 PHP 用在超大网站上的弱势
这年头不管你用 apache 还是 nginx,通常你的后端会用 php-fpm 来帮你处理 PHP
他会先帮你长出一群 PHP process 在后台等著
一只 process 同时间只处理一个 request
类似银行有固定数量的柜台人员,柜台一次只能服务一个人
web server 收到 request 之后会帮他抽号码
若柜台有空位就叫号引导 request 去柜台
若是有个 CPU 吃比较凶的奥客,那也只影响一个柜台,不会影响其他柜台的服务
这个模式的问题是,柜台不可能无限扩充,所以万一突然冲进一堆人,或者奥客太多
后面的 request 就整群得排队等柜台有空出来,跑不进 PHP
换句话说,一台 server 同时间能处理的 request 上限相对小(ex: 数十个)
与这个模式相对的是 nodejs 或 React PHP 那种 event loop 的做法。
不管来几个人,怎样反正就先收单下来
如果处理到一半发现有事情可以叫其他人(例如 DB)做
就把事情先推出去,然后处理下一个人。等到 DB 把结果发回来,再回头来处理。
这种一个棋王同时跟一群人下棋的搞法,好处是可以同时应付一大群人还不会明显变慢
甚至能应付有人虽然不吵不闹但一直待在柜台不走(长时间连线)
坏处是只要有一个奥客吃比较多 CPU 资源,用掉棋王的脑力,所有人都得陪他一起慢
所以传统(?) PHP 能够同时应付比较多的奥客,但对简单的事情的容量无法大幅提升
也无法应付长时间连线
而 event loop 能够同时应付大量逻辑简单,或效能瓶颈在 IO(如数据库)的的请求
但如果 server 需要处理复杂的商业逻辑就会卡弹
与其说弱势,问题终究是“打群架的时候角色适不适合”
话说回来,如果设定没有问题,机器也不要小的太夸张
php-fpm 一秒处理到上百个 request 并不难
如果你的网页一秒被戳不到一次,上面的考量都只是脑内运动,实务上没有差
: 然而,我已经使用PHP做为后端语言已经好几年了
: 听到老师这番话要我全部改学另一种语言而且又要把先前已写好好几万行的PHP码全部都
: 改写
: 我认为这是个相当相当浩大的工程
: 希望各位可以给些建议和看法
: 谢谢
PHP 的安全性问题,来自于他让开发者可以轻松的行恶
作为开发者,解决方法是自己应该比其他人认真追寻这些知识
推荐的起点有
- http://phptherightway.p2hp.com/
- Laravel Taiwan 那份好像有点旧了
- https://www.tenlong.com.tw/products/9789863477785
- 我竟然想不到 PHP 7 时代的推荐书,可能我太久没看书...
至于改写,建议判断条件是...这会不会影响你的分数(汗
作者: MOONRAKER (㊣牛鹤鳗毛人)   2020-05-17 00:35:00
作者: st1009 (前端攻城师)   2020-05-17 10:27:00
推推
作者: shvanta (vant)   2020-05-18 22:18:00
GALINE 大的文章都超赞
作者: Wujidadi (恨铁不成岗)   2020-05-22 22:19:00
作者: aaaaitw (爱潜水)   2020-05-22 23:35:00
谢谢大师指导
作者: seanlegend (seanlegend)   2020-06-13 23:58:00
学习了
作者: onegoman (SKY)   2020-06-22 21:01:00
作者: ssszl (苍月)   2020-06-23 09:36:00
推 好文
作者: newhandfun (新手方)   2020-06-25 11:41:00
路过不知道发生什么事但认同给推
作者: hikkijojo (Nash)   2020-07-09 17:04:00
谢大师 学习了
作者: dq042000   2020-11-13 19:32:00
推!

Links booklink

Contact Us: admin [ a t ] ucptt.com