Detailed explanation of the working mechanism of Session and security issues (explanation of PHP examples)_PHP tutorial

WBOY
Release: 2016-07-13 10:34:20
Original
769 people have browsed it

Let’s first briefly understand some knowledge of http to understand the stateless nature of the protocol. Then, learn some basic operations about cookies. Finally, I will explain step by step how to use some simple and efficient methods to improve the security and stability of your PHP application.

I think most junior PHP programmers will think that the security of PHP's default session mechanism seems to be guaranteed. In fact, it is exactly the opposite - the PHP team only provides a set of convenient session solutions for programs. As for security, it should be strengthened by programmers. This is the responsibility of the application development team. Because there are many methods, so to speak, there is no best, only better. The methods of attack are constantly changing, and the defenders also need to constantly change their tactics. Therefore, I personally think the approach of the PHP team is relatively wise.

1. HTTP statelessness

Http is a stateless protocol. This is because this protocol does not require the browser to identify itself in each request, and the browser and the server do not maintain a persistent connection for access between multiple pages. When a user visits a site, the user's browser sends an http request to the server, and the server returns an http response to the browser. In fact, it is a very simple concept. The client makes a request and the server replies. This is the entire communication process based on the http protocol.
Because web applications communicate based on the http protocol, and we have already mentioned that http is stateless, this increases the difficulty of maintaining the state of web applications, which is a big problem for developers. challenge. Cookies were born as an extension of http. Their main purpose is to make up for the stateless characteristics of http and provide a way to maintain the state between the client and the server. However, due to security considerations, some users Cookies are disabled in the browser. In this case, the status information can only be passed to the server through the parameters in the URL, but the security of this method is very poor. In fact, according to the usual thinking, there should be a client to identify itself and maintain a state with the server. However, for security reasons, we should all understand one thing - the information from the client cannot Completely trustworthy.
Despite this, there are relatively elegant solutions to the problem of maintaining web application state. However, it should be said that there is no perfect solution, and no matter how good the solution is, it cannot be suitable for all situations. This article will introduce some techniques. These technologies can be used to maintain the state of the application more stably and resist some attacks against the session, such as session hijacking. And you can learn how cookies work, what PHP sessions do, and how to hijack sessions.

2. HTTP Overview

How can you maintain the status of your web application and choose the most appropriate solution? Before answering this question, you must first understand the underlying protocol of the web - Hypertext Transfer Protocol (HTTP).

When a user accesses the domain name http://example.com, the browser will automatically establish a tcp/ip connection with the server, and then send an http request to port 80 of the example.com server. The syntax of this request is as follows:

Copy code The code is as follows:

GET / HTTP/1.1
Host : example.org
 

以上第一行叫做请求行,第二个参数(一个反斜线在这个例子中)表示所请求资源的路径。反斜线代表了根目录;服务器会转换这个根目录为服务器文件系统中的一个具体目录。
Apache的用户常用DocumentRoot这个命令来设置这个文档根路径。如果请求的url是http://example.org/path/to/script.php,那么请求的路径就是/path/to/script.php。假如document root 被定义为usr/lcoal/apache/htdocs的话,整个请求的资源路径就是/usr/local/apache/htdocs/path/to/script.php。
第二行描述的是http头部的语法。在这个例子中的头部是Host, 它标识了浏览器希望获取资源的域名主机。还有很多其它的请求头部可以包含在http请求中,比如user-Agent头部,在php可以通过$_SERVER['HTTP_USER_AGENT']获取请求中所携带的这个头部信息。
但是遗憾的是,在这个请求例子中,没有任何信息可以唯一标识当前这个发出请求的客户端。有些开发者借助请求中的ip头部来唯一标识发出此次请求的客户端,但是这种方式存在很多问题。因为,有些用户是通过代理来访问的,比如用户A通过代理B连接网站www.example.com, 服务器端获取的ip信息是代理B分配给A的ip地址,如果用户这时断开代理,然后再次连接代理的话,它的代理ip地址又再次改变,也就说一个用户对应了多个ip地址,这种情况下,服务器端根据ip地址来标识用户的话,会认为请求是来自不同的用户,事实上是同一个用户。 还用另外一种情况就是,比如很多用户是在同一个局域网里通过路由连接互联网,然后都访问www.example.com的话,由于这些用户共享同一个外网ip地址,这会导致服务器认为这些用户是同一个用户发出的请求,因为他们是来自同一个ip地址的访问。
保持应用程序状态的第一步就是要知道如何来唯一地标识每个客户端。因为只有在http中请求中携带的信息才能用来标识客户端,所以在请求中必须包含某种可以用来标识客户端唯一身份的信息。Cookie设计出来就是用来解决这一问题的。

三、cookies

如果你把Cookies看成为http协议的一个扩展的话,理解起来就容易的多了,其实本质上cookies就是http的一个扩展。有两个http头部是专门负责设置以及发送cookie的,它们分别是Set-Cookie以及Cookie。当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie这个头部时,意思就是指示客户端建立一个cookie,并且在后续的http请求中自动发送这个cookie到服务器端,直到这个cookie过期。如果cookie的生存时间是整个会话期间的话,那么浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端。一个cookie的设置以及发送过程分为以下四步:

1.客户端发送一个http请求到服务器端
2.服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
3.客户端发送一个http请求到服务器端,其中包含Cookie头部
4.服务器端发送一个http响应到客户端
这个通讯过程也可以用以下下示意图来描述:

Detailed explanation of the working mechanism of Session and security issues (explanation of PHP examples)_PHP tutorial
 

The Cookie header included in the client's second request provides the server with information that can be used to uniquely identify the client. At this time, the server can also determine whether the client has enabled cookies. Although it is possible for a user to suddenly disable the use of cookies while interacting with an application, this is so unlikely that it can be ignored, and this has proven to be true in practice.

4. get and post data

In addition to cookies, the client can also include data sent to the server in the requested URL, such as request parameters or request path. Let’s look at an example:

Copy code The code is as follows:

GET /index.php?foo=bar HTTP/1.1
Host: example.org

The above is a regular http get request. The get request is sent to the index.php script under the web server corresponding to the example.org domain name. In the index.php script, it can be obtained through $_GET['foo'] The value of the foo parameter in the corresponding url, which is 'bar'. Most PHP developers call such data GET data, and a few call it query data or url variables. But everyone needs to pay attention to one thing. It does not mean that GET data can only be included in HTTP GET type requests. GET data can also be included in HTTP POST type requests. As long as the relevant GET data is included in the requested URL, that is. That is to say, the delivery of GET data does not depend on the specific request type.

Another way for the client to pass data to the server is to include the data in the content area of ​​the http request. This method requires the request type to be POST. See the following example:

Copy code The code is as follows:

POST / index.php HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

In this case, the corresponding value bar can be obtained by calling $_POST['foo'] in the script index.php. Developers call this data POST data, which is the well-known form submission method in post mode.

In one request, both forms of data can be included:

Copy code The code is as follows:

POST /index.php?myget=foo HTTP/1.1
Host: example.orgContent-Type: application/x-www-form-urlencoded
Content-Length: 11

mypost=bar
[code]
These two methods of transmitting data are more stable than using cookies to transmit data, because cookies may be disabled, but this does not exist when transmitting data in GET and POST methods. We can include the PHPSESSID in the http request url, like the following example:
[code]
GET /index.php?PHPSESSID=12345 HTTP/1.1
Host: example.org

If you pass the session id in this way, you can achieve the same effect as passing the session id using the cookie header. However, the disadvantage is that the developer needs to append the session id to the URL or add it as a hidden field. in the form. Unlike cookies, as long as the server instructs the client to successfully create a cookie, the client will automatically pass the corresponding unexpired cookie to the server in subsequent requests. Of course, after turning on session.use_trans_sid, PHP can also automatically append the session id to the URL and the hidden field of the form, but it is not recommended to turn this option on because there are security issues. In this case, it is easy to leak the session ID. For example, some users will bookmark a URL or share a URL, then the session ID will be exposed. If the session ID has not expired, there will be certain security issues unless the server side , in addition to the session id, other methods are also added to verify the legitimacy of the user!

Although it is much safer to pass the session id in POST than GET. However, the disadvantage of this method is that it is more troublesome, because in this case, it is obviously not appropriate to convert all requests into post requests in your application.

5. Session management

Until now, I have only discussed how to maintain the state of the application, and only briefly touched on how to maintain the relationship between requests. Next, I will explain a technology that is used more in practice – Session management. When it comes to session management, it is not just about maintaining the state between each request, but also needing to maintain the data used for each specific user during the session. We often call this data session data because this data is associated with the session between a specific user and the server. If you use PHP's built-in session management mechanism, the session data is generally saved in the server-side folder /tmp, and the session data will be automatically saved to the super array $_SESSION. One of the simplest examples of using sessions is to pass relevant session data from one page (note: what is actually passed is the session id) to another page. The following uses sample code 1, start.php, to demonstrate this example:

Sample code 1 – start.php

Copy code The code is as follows:


If the user clicks the link in start.php to access continue.php, then the start.php can be obtained through $_SESSION['foo'] in continue.php. The defined value 'bar' in php. Look at the sample code 2 below:

Sample code 2 – continue.php

Copy code The code is as follows:
                                 🎜> session_start();
echo $_SESSION['foo']; /* bar */
?-->

   
是不是非常简单,但是我要指出的话,如果你真的这样来写代码的话,说明你对php底层的对于session的实现机制还不是非常了解透彻。在不了解php内部给你自动做了多少事情的情况下,你会发现如果程序出错的话,这样的代码将变的很难调试,事实上,这样的代码也完全没有安全性可言。

六、session的安全性问题

一直以来很多开发者都认为php内置的session管理机制是具有一定的安全性,可以对一般的session攻击起到防御。事实上,这是一种误解,php团队只实现了一种方便有效的机制。具体的安全措施,应该有应用程序的开发团队来实施。 就像开篇谈到的,没有最好的解决方案,只有最合适你的方案。

现在,我们来看下一个比较常规的针对session的攻击:

1..用户访问http://www.example.org,并且登录。
2.example.org的服务器设置指示客户端设置相关cookie – PHPSESSID=12345
3.攻击者这时访问http://www.example.org/,并且在请求中携带了对应的cookie – PHPSESSID=12345
4.这样情况下,因为example.orge的服务器通过PHPSESSID来辨认对应的用户的,所以服务器错把攻击者当成了合法的用户。
整个过程的描述,请看下面的示例图:

Detailed explanation of the working mechanism of Session and security issues (explanation of PHP examples)_PHP tutorial
 

Of course, the prerequisite for this attack method is that the attacker must fix, hijack or guess the PHPSESSID of a legitimate user by some means. Although this seems very difficult, it is not impossible.

7. Security enhancement

There are many techniques that can be used to strengthen Session security. The main idea is to make the verification process as simple as possible for legitimate users, and then make the steps as complex as possible for attackers. Of course, this seems to be a difficult balance, and the decision should be made based on the specific design of your application.

The simplest HTTP/1.1 request includes the request line and some Host headers:

Copy the code The code is as follows:

GET / HTTP/1.1
Host: example.org

If the client passes the relevant session identifier through PHPSESSID, the PHPSESSID can be passed in the cookie header:
Copy code The code is as follows:
 
                                                                                                        =12345


Similarly, the client can also pass the session identifier in the requested URL.


Copy code The code is as follows:
GET /?PHPSESSID=12345
HTTP/1.1Host: example.org


Of course, the session identifier can also be included in the POST data, but this has an impact on the user experience, so this method is rarely used.

Because information from TCP/IP may not be completely trusted, it is not appropriate for web developers to use information in TCP/IP to enhance security. However, the attacker must also provide a unique identifier of a legitimate user in order to pretend to be a legitimate user and enter the system. Therefore, it seems that the only effective way to protect the system is to hide the session identifier as much as possible or make it difficult to guess. It would be best if both could be implemented.

PHP will automatically generate a random session ID, which is basically impossible to guess, so the security in this area is still guaranteed. However, it is quite difficult to prevent attackers from obtaining a legitimate session ID, which is basically beyond the control of developers.

In fact, many situations may lead to the leakage of session ID. For example, if the session ID is passed through GET data, this sensitive identity information may be exposed. Because some users may cache, save, or send links with session IDs in email content. Cookies are a relatively secure mechanism, but users can disable cookies in the client! There are also serious security vulnerabilities in some IE versions. The most famous one is that it leaks cookies to some evil sites with security risks.

Therefore, as a developer, you can be sure that the session ID cannot be guessed, but it may still be obtained by an attacker using certain methods. Therefore, some additional security measures must be taken to prevent such situations from happening in your application.

In fact, in addition to the mandatory headers such as Host, a standard HTTP request also contains some optional headers. For an example, look at the following request:


Copy code The code is as follows:
GET / HTTP/1.1
Host: example.org
Cookie: PHPSESSID=12345
User-Agent : Mozilla/5.0 (Macintosh; U; Intel Mac OS = 0.1 Accept-Charset: ISO-8859-1, UTF-8; q = 0.66, *; q = 0.66
Accept-Language: EN


We can see that the above request example contains four additional headers, namely User-Agent, Accept, Accept-Charset and Accept-Language. Because these headers are not required, it would be unwise to rely solely on them to function in your application. However, if a user's browser does send these headers to the server, then it is certain that subsequent requests sent by the same user through the same browser will also carry these headers. Of course, there will be very few special circumstances. If the above example is a request made by a user who currently has a session with the server, consider the following request:

Copy code The code is as follows:

GET / HTTP/1.1
Host: example.org
Cookie: PHPSESSID=12345
User-Agent: Mozilla/5.0


Because the same session id is included in the cookie header of the request, the same php session will be accessed. However, the User-Agent header in the request is different from the information in the previous request. Can the system assume that the two requests are made by the same user?

In this case, if you find that the header of the browser has changed, but you are not sure whether this is a request from the attacker, a better measure is to pop up an input box asking for a password for the user to enter, like this If so, the impact on user experience will not be great and attacks can be effectively prevented.

Of course, you can add code to check the User-Agent header in the system, similar to the code in Example 3:

Sample code 3:

Copy code The code is as follows: ();
                                                                                                                                                                                                           The agent information is saved in the session, similar to the code in Example 4 below:

Sample code 4:



Copy the code

The code is as follows: ();

$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);

?-->


Although it is not necessarily necessary to use MD5 to encrypt the User-Agent information, there is no need to filter the $_SERVER['HTTP_USER_AGENT'] data in the future. Otherwise, data filtering must be performed before using this data, because any data from the client is not trustworthy, so attention must be paid to this. After you check the User-Agent client header information, as an attacker you must complete two steps to hijack a session: 1. Obtain a valid session id
2. Include the same User-Agent header in the forged request

You may say that the attacker can actually obtain a valid session id , then with his level, it is not difficult to forge an identical User-Agent. Yes, but we can say that this at least adds some trouble to him, and also increases the security of the session mechanism to a certain extent.

You should also be able to think of it. Since we can check the User-Agent header to enhance security, we might as well use other header information, combine them to generate an encrypted token, and let the client Carry this token in subsequent requests! In this case, it is basically impossible for an attacker to guess how such a token is generated. This is like using a credit card to pay in a supermarket. You must have a credit card (such as a session ID), and you must also enter a payment password (such as a token). Only when both of these are met, can you successfully enter the account to pay. . Look at the following piece of code:



Copy the code
The code is as follows:



                                                                                                                                                        >
?-->


Note: The Accept header should not be used to generate tokens, because some browsers will automatically change this header when the user refreshes the browser .

After adding this very difficult-to-guess token to your verification mechanism, security will be greatly improved. If this token is passed like a session id, in this case, an attacker must complete the necessary 3 steps to hijack the user's session:

1. Obtain a legal session ID2. Add the same User-Agent header to the request and use it to generate a token

3. Carry the attacker’s token in the request

4 .There is a problem here. If the session ID and token are both passed through GET data, then an attacker who can obtain the session ID can also obtain the token. Therefore, a safer and more reliable way should be to use two different data transfer methods to transfer session id and token respectively. For example, pass the session id through cookie, and then pass the token through GET data. Therefore, if an attacker obtains this unique user identity through some means, it is unlikely that he can easily obtain this token at the same time. It is still relatively safe.


There are many technical means that can be used to enhance the security of your session mechanism. I hope that after you have a rough understanding of the internal nature of the session, you can design a verification mechanism suitable for your application system, thereby greatly improving the security of the system. After all, you are one of the developers who is most familiar with the system you are developing and can implement some unique and additional security measures based on the actual situation.

8. Summary

The above only briefly describes the working mechanism of session and briefly explains some security measures. But remember, the above methods can enhance security, but they do not mean that they can completely protect your system. I hope readers will investigate the relevant content themselves. During this research process, I believe you will learn solutions that are of great practical value.

http://www.bkjia.com/PHPjc/751932.html

www.bkjia.com

http: //www.bkjia.com/PHPjc/751932.htmlTechArticleLet’s first briefly understand some knowledge of http to understand the stateless nature of the protocol. Then, learn some basic operations about cookies. Finally, I will explain step by step how to use a...
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template