A brief discussion on Php security and preventing Sql injection, preventing Xss attacks, preventing hot links, and preventing CSRF
Foreword:
First of all, the author is not an expert in web security, so this is not an expert-level article on web security. It is a study note and a careful summary of the article. There are some things in it that we phpers cannot easily discover or do not pay attention to. So I wrote it down for easy reference later. There must be dedicated web security testers in large companies, and security is not the scope of PHPer's consideration. But as a PHPer, the security knowledge is: "Knowing that there is such a thing, you will naturally pay attention to it when programming."
Directory:
1. Some php security configurations
(1) Turn off the php error prompt function
(2) Turn off some "bad functions"
( 3) Strictly configure file permissions.
2. Strict data verification, not all your users are "good" people
2.1 In order to ensure the security and robustness of the program, data verification should include content.
2.2 Programmers can easily miss points or things that need attention
3. Anti-injection
3.1 Simple judgment of whether there is an injection vulnerability and the principle
3.2 Common mysql injection statements
(1) No username and password required
(2) Using a user without entering a password
(3) Guessing a user’s password
(4) Elevating privileges when inserting data
(5) Update The same applies to privilege escalation and insertion
(6) Malicious update and deletion
(7) Union, join, etc.
(8) Wildcard symbols %, _
(9) There are many guess tables Information injection sql
33 Some methods to prevent injection
2.3.1 Some functions and precautions that PHP can use to prevent injection.
2.3.2 Anti-injection character priority.
2.3.3 Anti-injection code
(1) If the parameter is a number, use the intval() function directly
(2) Filtering of non-text parameters
(3) Text data anti-injection code.
(4) Of course there are other codes combined with addslashes and mysql_escape_string.
4. Prevent xss attacks
4.1Xss attack process
4.2 Common xss attack places
4.3 Anti-XSS methods
5. CSRF
5.1 Brief explanation of CSRF principles
5.2 Prevention methods
6. Anti-hotlinking
7. Anti-CC attack
1. Some php security configurations
(1) Turn off the php error prompt function
Change display_errors in php.ini to
1) Use error_reporting(0); Failure example:
A file code:
(2) Turn off some "bad features"
1) Turn off the magic quotes function
Put magic_quotes_gpc = OFF in php.iniAvoid repeated escaping with addslashes
2) Turn off register_globals = Off
With register_globals = ON
Address column: http://www.jb51.net?bloger=benwin
Copy code
这种情况下会导致一些未初始化的变量很容易被修改,这也许是致命的。所以把register_globals = OFF关掉
(3)严格配置文件权限。
为相应文件夹分配权限,比如包含上传图片的文件不能有执行权限,只能读取
2、严格的数据验证,你的用户不全是“好”人。
记得笔者和一个朋友在讨论数据验证的时候,他说了一句话:你不要把你用户个个都想得那么坏!但笔者想说的这个问题不该出现在我们开发情景中,我们要做的是严格验证控制数据流,哪怕10000万用户中有一个是坏用户也足以致命,再说好的用户也有时在数据input框无意输入中文的时,他已经不经意变“坏”了。
2.1为了确保程序的安全性,健壮性,数据验证应该包括
(1) 关键数据是否存在。如删除数据id是否存在
(2) 数据类型是否正确。如删除数据id是否是整数
(3) 数据长度。如字段是char(10)类型则要strlen判断数据长度
(4) 数据是否有危险字符
数据验证有些人主张是把功能完成后再慢慢去写安全验证,也有些是边开发边写验证。笔者偏向后者,这两种笔者都试过,然后发现后者写的验证相对健壮些,主要原因是刚开发时想到的安全问题比较齐全,等开发完功能再写时有两个问题,一个phper急于完成指标草草完事,二是确实漏掉某些point。
2.2程序员容易漏掉point或者说需要注意的事项:
(1) 进库数据一定要安全验证,笔者在广州某家公司参与一个公司内部系统开发的时候,见过直接把$_POST数据传给类函数classFunctionName($_POST),理由竟然是公司内部使用的,不用那么严格。暂且不说逻辑操作与数据操控耦合高低问题,连判断都没判断的操作是致命的。安全验证必须,没任何理由推脱。
(2) 数据长度问题,如数据库建表字段char(25),大多phper考虑到是否为空、数据类型是否正确,却忽略字符长度,忽略还好更多是懒于再去判断长度。(这个更多出现在新手当中,笔者曾经也有这样的思想)
(3) 以为前端用js判断验证过了,后台不需要判断验证。这也是致命,要知道伪造一个表单就几分钟的事,js判断只是为了减少用户提交次数从而提高用户体验、减少http请求减少服务器压力,在安全情况下不能防“小人”,当然如果合法用户在js验证控制下是完美的,但作为phper我们不能只有js验证而抛弃再一次安全验证。
(4) 缺少对表单某些属性比如select、checkbox、radio、button等的验证,这些属性在web页面上开发者已经设置定其值和值域(白名单值),这些属性值在js验证方面一般不会验证,因为合法用户只有选择权没修改权,然后phper就在后端接受数据处理验证数据的时候不会验证这些数据,这是一个惯性思维,安全问题也就有了,小人一个伪表单。
(5) 表单相应元素name和数据表的字段名一致,如用户表用户名的字段是user_name,然后表单中的用户名输入框也是user_name,这和暴库没什么区别。
(6) 过滤危险字符方面如防注入下面会独立讲解。
3、防注入
3.1简单判断是否有注入漏洞以及原理。
网址:http://www.jb51.net/benwin.php?id=1 运行正常,sql语句如:select * from phpben where id = 1
(1) 网址:http://www.jb51.net/benwin.php?id=1' sql语句如:select * from phpben where id = 1' 然后运行异常 这能说明benwin.php文件没有对id的值进行“'” 过滤和intval()整形转换,当然想知道有没有对其他字符如“%”,“/*”等都可以用类似的方法穷举测试(很多测试软件使用)
(2)网址:http://www.jb51.net/benwin.php?id=1 and 1=1 则sql语句可能是 select * from phpben where id = 1 and 1=1,运行正常且结果和http://www.jb51.net/benwin.php?id=1结果一样,则说明benwin.php可能没有对空格“ ”、和“and”过滤(这里是可能,所以要看下一点)
(3)网址:http://www.jb51.net/benwin.php?id=1 and 1=2则sql语句可能是 select * from phpben where id = 1 and 1=2 如果运行结果异常说明sql语句中“and 1=2”起作用,所以能3个条件都满足都则很确定的benwin.php存在注入漏洞。
ps:这里用get方法验证,post也可以,只要把值按上面的输入,可以一一验证。
3.2 Common mysql injection statements.
(1) No username and password required
(2) Take advantage of a user without entering the password.
(3) Guess a user’s password
(4) Elevate privileges when inserting data
(9) There are also a lot of guess table information injected into sql
Of course there are many more, and the author has not studied to the level of a professional. Here are some common ones, and they are what PHPer should know and master, instead of blindly copying and pasting some anti-injection codes online. However, I don't understand why.
The following anti-injection methods may be easier to understand in retrospect.
3.3 Some methods to prevent injection
3.3.1 Some functions and precautions that PHP can use to prevent injection.
(1)addslashes and stripslashes.
Addslashes add slashes "'", """, "\", "NULL" to these "'", """, "", "NULL". Stripslashes does the opposite. What should be noted here is php. Is magic_quotes_gpc=ON enabled in ini? Duplication will occur if addslashes is enabled. So when using it, you must first check with get_magic_quotes_gpc()
General code is similar:
mysql_real_escape_string can only be used under (PHP 4 >= 4.3.0, PHP 5). Otherwise, you can only use mysql_escape_string
to copy the code
3.3.2 Anti-injection character priority.
To prevent injection, you must first know what injection characters or keywords there are. Common mysql injection characters include character delimiters such as "'" and """; logical keywords such as "and" and "or"; mysql notes Characters such as "#", "–", "/**/"; mysql wildcard characters "%", "_"; mysql keyword "select|insert|update|delete|*|union|join|into|load_file|outfile ”
(1) For some parameters with prescribed formats, the highest priority for anti-injection is "space".
For example, some parameters such as bank card numbers, ID numbers, email addresses, phone numbers, birthdays, postal codes, etc. have their own formats and the format stipulates that there cannot be spaces. When filtering, spaces are generally filtered out first ( Including some space "variants"), because other characters define symbols, logical keywords, and mysql notes. Note that the following figure shows that the important ones are "'", " "
ps: Variants of space characters are: "%20", "n", "r", "rn", "nr", "chr("32″)" This is why mysql_escape_string() and mysql_real_escape_string() Two functions escape "n", "r". In fact, many PHPers only know how to escape n and r without knowing the reason. When MySQL parses n and r, they treat them as spaces. The author has tested and verified it, so I will not post the code here.
(2) “and”, “or”, “”, “#”, “–”
Logical key can combine many injected codes; mysql annotation annotates all the characters behind the inherent sql code so that the injected sql statement can run normally; "" can also combine many injected characters x00, x1a.
ps: SQL parsing "#" and "-" are not considered by most mysql anti-injection codes, and are also ignored by many phpers. Also, some PHPers use "-" to separate parameters when assigning values, so the author recommends not to write parameters in this way. Of course, you can also use "-" when filtering parameters (note that there are spaces. If there are no spaces, it will not be parsed as a note. Note) When filtering as a whole instead of filtering "-", this avoids excessive filtering parameters.
(3) "null", "%", "_"
These cannot be independent and should not be used under specific circumstances. For example, the wildcard characters "%, _" must be included in the mysql like clause. Therefore, the filtering of "%" and "_" is generally filtered only when the search is related. They cannot be included in the normal filtering queue, because some such as mailboxes can have the "_" character
(4) Keyword "select|insert|update|delete|*|union|join|into|load_file|outfile"
Maybe you will ask why these important keywords have such low priority. What the author wants to say is that these keywords are not harmful when purchased without "'", """, " ", "and", "or", etc. In other words, these keywords are not "independent" and "dependent" enough. "Exceptionally large. Of course, the low priority does not mean that it should not be filtered.
3.3.3 Anti-injection code.
(1) If the parameter is a number, use the intval() function directly
Note: Many popular anti-injection codes on the Internet are just filtered by addslashes(), mysql_escape_string(), mysql_real_escape_string() or any combination of the three. However, phper thinks it is filtered, and there are still loopholes if you are not careful, that is When the parameter is a number:
(2) Filtering of non-text parameters
Text parameters refer to titles, messages, content, etc. that may contain "'", "'", etc. It is impossible to escape or replace them all during filtering.
But non-text data is OK.
ps:还有一些从列表页操作过来的一般href是”phpben.php?action=delete&id=1”,这时候就注意啦,_str_replace($_GET['action'])会把参数过滤掉,笔者一般不用敏感关键作为参数,比如delete会写成del,update写成edite,只要不影响可读性即可;
还有上面代码过滤下划线的笔者注悉掉了,因为有些参数可以使用下划线,自己权衡怎么过滤;
有些代码把关键字当重点过滤对象,其实关键字的str_replace很容易“蒙过关”,str_replace(“ininsertsert”)过滤后的字符还是insert,所以关键的是其他字符而不是mysql关键字。
(3)文本数据防注入代码。
文本参数是指标题、留言、内容等这些数据不可能也用str_replace()过滤掉,这样就导致数据的完整性,这是很不可取的。
代码:
The anti-injection codes actually come and go in those combinations, and then they are adapted according to their own program codes. The author has not considered all of these codes. It is better that cookes, sessions, and requests are not fully filtered. The important thing is to know the principle, why these characters are filtered, and what harm the characters have.
4. Prevent xss attacks
XSS: cross site script, why is it not called css, so as not to be confused with div+css.
4.1Xss attack process:
(1) Found that station A has an xss vulnerability.
(2) Inject xss vulnerability code. It can be js code, Trojan horse, script file, etc. Here, if the benwin.php file of station A has a vulnerability.
(3) Use some methods to deceive relevant personnel of station A to run benwin.php, and use some member information of relevant personnel such as cookies, permissions, etc.
Related personnel:
Administrators (such as Tieba moderators) generally have certain permissions. The purpose is to borrow the administrator's authority or perform privilege escalation, add or add administrators, add backdoors, upload Trojans, or further penetrate and other related operations.
Members of Station A: Members run benwin.php of Station A. The purpose is generally to steal members’ information on site A.
Method:
1) Post information on site A to lure relevant people to benwin.php, such as a website address. This is local deception
2) Send deceptive information or emails on other websites.
Usually using disguised URLs to trick relevant personnel of station A into clicking into benwin.php
(4) The third step is usually an xss attack. If you want to attack further, repeat steps (2) and (3) to achieve the goal.
A simple example of xss attack
Code: benwin.php file