検索
ホームページバックエンド開発PHPの問題PHP セキュリティを開発する際に考慮すべきことは何ですか?

PHP セキュリティを開発する際に考慮すべきことは何ですか?

PHP セキュリティを開発する際には何を考慮する必要がありますか?

1, サイトの機密ディレクトリの漏洩を避けるために、サイト全体の構造を把握する

初めてコードを書き始めたとき、私はこう思いました。多くの古いソース コードと同様に、index.php、register.php、login.php をルート ディレクトリに置き、ユーザーが登録ページをクリックすると、http://localhost/register.php## にジャンプします。 #。このようなコード構造では、最大の問題はセキュリティではなく、コードの拡張と移植です。

コードを作成する過程で、コードを変更する必要が生じることがよくありますが、このとき、コードに統一されたエントリ ポイントがない場合、多くの箇所を変更する必要がある可能性があります。後で、emlog コードを少し読んだところ、Web サイトの実際のフロントエンド コードはテンプレート ディレクトリにあり、ルート ディレクトリにはエントリ ポイント ファイルと設定ファイルだけがあることがわかりました。そこでひらめき、Webサイト全体の構造を変更しました。

Web サイトのルート ディレクトリにエントリ ポイント ファイルを配置し、Web サイト全体のすべてのページを管理できるようにします。このとき、登録ページは

http://localhost/?act=register になります。 、どのページも act のパラメータにすぎません。このパラメータを取得した後、スイッチを使用して、含めるファイル コンテンツを選択します。このエントリ ポイント ファイルには、Web サイトの絶対パス、Web サイトのアドレス、データベース ユーザーのパスワードなどの定数の定義を含めることもできます。将来的には、スクリプトを作成するときに、相対パスの代わりに絶対パスを使用するようにします (そうしないと、スクリプトの場所が変更されると、コードも変更されます)。この絶対パスは、エントリ ポイント ファイルの定義から取得されます。

もちろん、セキュリティの観点から、エントリ ポイント ファイルはバックエンド アドレスを隠すこともできます。この

http://localhost/?act=xxx のようなアドレスは、バックグラウンドで絶対パスを公開せず、コードをあまり変更せずに頻繁に変更することもできます。エントリ ポイント ファイルは、管理者以外のページの表示が許可されていない Web サイトのバックエンドなど、訪問者の身元を確認することもできます。エントリ ポイント ファイルで本人確認を行うことができますが、ログインしていない場合は 404 ページが出力されます。

エントリ ポイント ファイルでは、すべての非エントリ ポイント ファイルの前に次の文を追加しました:

<?php 
if(!defined(&#39;WWW_ROOT&#39;))
 {
header("HTTP/1.1 404 Not Found");
 exit;
 } 
?>

WWW_ROOT はエントリ ポイントで定義した定数です。このページの絶対パス (

http://localhost/register.php) を指定すると、404 エラーが出力されます。エントリ ポイント (http://localhost/?act=register) 経由でのみアクセスします。 ) 次のコードを実行します。

2. SQL インジェクションを避けるためにプリコンパイルされたステートメントを使用する

インジェクションは以前は大きな問題でしたが、近年、誰もがこの問題に注目しているため、それで徐々に良くなってきています。

Wu Hanqing 氏が Web White Hat でよく言っていますが、実際、SQL インジェクションや XSS などの多くの脆弱性は、「データ」と「コード」を区別しません。 「コード」はプログラマーが記述するもの、「データ」はユーザーが変更できるものです。 SQL ステートメント

select * from admin where username='admin'password='xxxxx' を記述する場合、admin と xxxxx はデータであり、ユーザーが入力したユーザー名とパスワードですが、処理が行われない場合、ユーザー入力は「コード」(「または ''=」など)である可能性があり、脆弱性が生じます。ユーザーが「コード」にアクセスできないようにしてください。

PHP には、mysql データベース用の 2 つのモジュール、mysql と mysqli があります。Mysqli は、mysql の改善を意味します。 mysql の改良版であるこのモジュールには、「プリコンパイル」の概念が含まれています。上記の SQL ステートメントと同様に、次のように変更します。

select * from admin where username='?' Password='?' これは SQL ステートメントではありませんが、mysqli のプリコンパイル機能を使用して次のように実行できます。最初に stmt オブジェクトにコンパイルされ、後でユーザーがアカウントとパスワードを入力した後、stmt->bind_param を使用して、ユーザーが入力した「データ」をこれら 2 つの疑問符の位置にバインドします。このように、ユーザーが入力した内容はあくまで「データ」であり、「コード」にすることはできません。

これら 2 つの疑問符は、「データ」の場所と SQL ステートメントの構造を定義します。すべてのデータベース操作を 1 つのクラスにカプセル化でき、すべての SQL ステートメントの実行がプリコンパイルされます。これにより、Wu Hanqing が最も推奨するソリューションでもある SQL インジェクションが完全に回避されます。

以下は、mysqli を使用したコード部分です (関数の実行が成功したか失敗したかを決定するコードはすべて省略していますが、重要ではないという意味ではありません):

<?php
//用户输入的数据
$name = &#39;admin&#39;;
$pass = &#39;123456&#39;;
//首先新建mysqli对象,构造函数参数中包含了数据库相关内容。
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
//设置sql语句默认编码
$this->mysqli->set_charset("utf8");
//创建一个使用通配符的sql语句
$sql = &#39;SELECT user_id FROM admin WHERE username=? AND password=?;&#39;;
//编译该语句,得到一个stmt对象.
$stmt = $conn->prepare($sql);
/********************之后的内容就能重复利用,不用再次编译*************************/
//用bind_param方法绑定数据
//大家可以看出来,因为我留了两个?,也就是要向其中绑定两个数据,所以第一个参数是绑定的数据的类型(s=string,i=integer),第二个以后的参数是要绑定的数据
$stmt->bind_param(&#39;ss&#39;, $name, $pass);
//调用bind_param方法绑定结果(如果只是检查该用户与密码是否存在,或只是一个DML语句的时候,不用绑定结果)
//这个结果就是我select到的字段,有几个就要绑定几个
$stmt->bind_result($user_id);
//执行该语句
$stmt->execute();
//得到结果
if($stmt->fetch()){
 echo &#39;登陆成功&#39;;
 //一定要注意释放结果资源,否则后面会出错
 $stmt->free_result();
 return $user_id; //返回刚才select到的内容
}else{echo &#39;登录失败&#39;;}
?>

3. 防止 XSS コード、Cookie を使用する必要がない場合は、使用しないでください

私は自分の Web サイトで Cookie を使用しておらず、アクセス許可を厳しく制限しているため、 XSS のリスクは比較的小さいです。

xss の防御にも同様の原則が適用され、「コード」と「データ」の関係を適切に扱います。もちろん、ここでのコードは JavaScript コードまたは HTML コードを指します。ユーザーが制御できるコンテンツについては、htmlspecialchars などの関数を使用してユーザーが入力したデータを処理し、JavaScript でページにコンテンツを出力するように注意する必要があります。

4. ユーザー権限を制限し、CSRF を防止します

现在脚本漏洞比较火的就是越权行为,很多重要操作使用GET方式执行,或使用POST方式执行而没有核实执行者是否知情。

CSRF很多同学可能比较陌生,其实举一个小例子就行了:

A、B都是某论坛用户,该论坛允许用户“赞”某篇文章,用户点“赞”其实是访问了这个页面:http://localhost/?act=support&articleid=12。这个时候,B如果把这个URL发送给A,A在不知情的情况下打开了它,等于说给articleid=12的文章赞了一次。

所以该论坛换了种方式,通过POST方式来赞某篇文章。

<form action="http://localhost/?act=support" method="POST">
 <input type="hidden" value="12" name="articleid">
 <input type="submit" value="赞">
</form>

可以看到一个隐藏的input框里含有该文章的ID,这样就不能通过一个URL让A点击了。但是B可以做一个“极具诱惑力”的页面,其中某个按钮就写成这样一个表单,来诱惑A点击。A一点击,依旧还是赞了这篇文章。

最后,该论坛只好把表单中增加了一个验证码。只有A输入验证码才能点赞。这样,彻底死了B的心。

但是,你见过哪个论坛点“赞”也要输入验证码?

所以吴翰清在白帽子里也推荐了最好的方式,就是在表单中加入一个随机字符串token(由php生成,并保存在SESSION中),如果用户提交的这个随机字符串和SESSION中保存的字符串一致,才能赞。

在B不知道A的随机字符串时,就不能越权操作了。

我在网站中也多次使用了TOKEN,不管是GET方式还是POST方式,通常就能抵御99%的CSRF估计了。

5、严格控制上传文件类型

上传漏洞是很致命的漏洞,只要存在任意文件上传漏洞,就能执行任意代码,拿到webshell。

我在上传这部分,写了一个php类,通过白名单验证,来控制用户上传恶意文件。在客户端,我通过javascript先验证了用户选择的文件的类型,但这只是善意地提醒用户,最终验证部分,还是在服务端。

白名单是必要的,你如果只允许上传图片,就设置成array('jpg','gif','png','bmp'),当用户上传来文件后,取它的文件名的后缀,用in_array验证是否在白名单中。

在上传文件数组中,会有一个MIME类型,告诉服务端上传的文件类型是什么,但是它是不可靠的,是可以被修改的。在很多存在上传漏洞的网站中,都是只验证了MIME类型,而没有取文件名的后缀验证,导致上传任意文件。

所以我们在类中完全可以忽略这个MIME类型,而只取文件名的后缀,如果在白名单中,才允许上传。

当然,服务器的解析漏洞也是很多上传漏洞的突破点,所以我们尽量把上传的文件重命名,以“日期时间+随机数+白名单中后缀”的方式对上传的文件进行重命名,避免因为解析漏洞而造成任意代码执行。

6、加密混淆javascript代码,提高攻击门槛

很多xss漏洞,都是黑客通过阅读javascript代码发现的,如果我们能把所有javascript代码混淆以及加密,让代码就算解密后也是混乱的(比如把所有变量名替换成其MD5 hash值),提高阅读的难度。

7、使用更高级的hash算法保存数据库中重要信息

这个硬盘容量大增的时期,很多人拥有很大的彩虹表,再加上类似于cmd5这样的网站的大行其道,单纯的md5已经等同于无物,所以我们迫切的需要更高级的hash算法,来保存我们数据库中的密码。

所以后来出现了加salt的md5,比如discuz的密码就是加了salt。其实salt就是一个密码的“附加值”,比如A的密码是123456,而我们设置的salt是abc,这样保存到数据库的可能就是md5('123456abc'),增加了破解的难度。

但是黑客只要得知了该用户的salt也能跑md5跑出来。因为现在的计算机的计算速度已经非常快了,一秒可以计算10亿次md5值,弱一点的密码分把钟就能跑出来。

所以后来密码学上改进了hash,引进了一个概念:密钥延伸。说简单点就是增加计算hash的难度(比如把密码用md5()函数循环计算1000次),故意减慢计算hash所用的时间,以前一秒可以计算10亿次,改进后1秒只能计算100万次,速度慢了1000倍,这样,所需的时间也就增加了1000倍。

那么对于我们,怎么使用一个安全的hash计算方法?大家可以翻阅emlog的源码,可以在include目录里面找到一个HashPaaword.php的文件,其实这就是个类,emlog用它来计算密码的hash。

このクラスには特徴があります。計算されるハッシュ値は毎回異なります。そのため、ハッカーはレインボー テーブルなどの方法でパスワードを解読することはできません。ハッカーは、このクラスの checkpassword メソッドを使用して、入力されたパスワードの正しさを返すことしかできません。ユーザー。また、この機能はハッシュの計算時間を意図的に長くするため、ハッカーが取得したハッシュ値を解読することが困難になります。

最新のphp5.5ではこのハッシュアルゴリズムが正式な機能となり、将来的にはこの機能を利用してパスワードをハッシュ化できるようになります

8. 認証コードセキュリティ

検証コードは通常、PHP スクリプトによって生成されたランダムな文字列で、GD ライブラリによって処理されて画像化されます。実際の検証コード文字列は SESSION に保存され、生成された画像がユーザーに表示されます。ユーザーが検証コードを入力して送信すると、SESSION 内の検証コードがサーバー上で比較されます。

これを見て、私が以前犯した間違いを思い出しました。検証コードの比較が完了した後、それが正しいか間違っているかにかかわらず、SESSIONをクリアしませんでした。これにより問題が発生します。ユーザーが初めて検証コードを送信すると、2 回目以降は検証コードを生成するスクリプトにアクセスできなくなります。このとき、SESSION 内の検証コードは更新または削除されません。 、検証コードが再利用されることになりますが、検証の目的には役立ちません。

認証コードが認識されない問題について話します 私は emlog を含む WordPress プログラムをよく参考にしていますが、その認証コードは褒められたものではありません。検証コードが機械に認識された後に多くのスパムコメントが生成されたため、その後、w3cが推奨していると言われているより複雑な検証コードを使用しました。

そうですね、実際のアプリケーションで使用できるものは、私が思いつく限りたくさんあります。これは、私が独自のコードを書いている間に蓄積した、コードのセキュリティに関する洞察のほんの一部です。もっと良いアイデアがある場合は、私と連絡してください。皆さんもより安全なコードを書けるようになってほしいと思います。

上記の内容は参考用です。

推奨ビデオ チュートリアル: PHP ビデオ チュートリアル

以上がPHP セキュリティを開発する際に考慮すべきことは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は脚本之家で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン