We understand the stateless nature of the protocol by simply understanding some of the HTTP knowledge. Then, learn some basic things about cookies. Finally, I'll step through how to use some simple, efficient ways to improve the security of your PHP application and stabilize the line.
I think most of the PHP junior programmers will assume that PHP default session mechanism security seems to be guaranteed, the fact that the –php team just provides a set of convenient session solution for programmers to use, as for security, should be by the programmer to strengthen, This is the responsibility of the application development team. Because, there are a lot of methods, so to speak, no best, only better. The way the attack is constantly changing, the defensive side also needs to constantly change, so I personally think the PHP team's approach is more sensible.
First, HTTP stateless
HTTP is a stateless protocol. This is because the 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 accesses 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, a very simple concept, the client a request, the server side of a reply, this is the entire HTTP protocol-based communication process.
Because the Web application communicates based on the HTTP protocol, and we've already talked about HTTP being stateless, this increases the difficulty of maintaining the state of the Web application, which is a challenge for developers. Cookies are created as an extension of HTTP, and its main purpose is to compensate for the stateless nature of HTTP, providing a way to maintain state between the client and server, but for security reasons, some users are prohibited from cookies in the browser. In this case, the state information can only be passed to the server side through the parameters in the URL, but this is a very poor security method. In fact, according to the usual idea, there should be a client to identify itself, thus maintaining a state with the server, but for security reasons we should all understand that the information from the client is not fully trusted.
In spite of this, there is a relatively elegant solution to the problem of maintaining the state of the Web application. However, it should be said that there is no perfect solution, and no good solution can be applied in all cases. This article will cover some techniques. These techniques can be used to maintain the state of the application more stably and to withstand some attacks against the session, such as conversation hijacking. And you can learn how cookies work, what the PHP session does, and how to hijack the session.
Second, HTTP overview
How can you maintain the state of your Web application and choose the most appropriate solution? Before you answer this question, you must first understand the web's underlying protocol –hypertext Transfer Protocol (HTTP).
When the user accesses the domain name http://example.com, the browser automatically establishes a TCP/IP connection with the server and then sends an HTTP request to port 80 of the example.com server. The syntax for this request is as follows: The
copy Code code is as follows:
get/http/1.1
Host:example.org
The first line above is called the request line, and the second parameter (a backslash in this example) represents the path of the requested resource. The backslash represents the root directory, and the server converts the root directory to a specific directory in the server file system.
Apache users often documentroot this command to set the root path of this document. If the requested URL is http://example.org/path/to/script.php, then the requested path is/path/to/script.php. If document root is defined as Usr/lcoal/apache/htdocs, the resource path for the entire request is/usr/local/apache/htdocs/path/to/script.php.
The second line describes the syntax of the HTTP header. The header in this example is host, which identifies the domain host that the browser wants to get resources for. There are many other request headers that can be included in the HTTP request, such as the user-agent header, where PHP can get the header information that is carried in the request via $_server[' Http_user_agent '.
Unfortunately, in this request example, there is no information that uniquely identifies the current client making the request. Some developers use the IP header in the request to uniquely identify the client that made the request, but there are many problems with this approach. Because, some users are accessed through the proxy, such as User A through proxy b to connect to the site www.example.com, the server to obtain the IP information is agent B assigned to a IP address, if the user then disconnects the agent, and then connect the agent again, its proxy IP address again change, Also say that a user corresponds to multiple IP addresses, in this case, the server side according to the IP address to identify the user, it will be considered that the request is from a different user, in fact, the same user. In another case, for example, many users are connected to the Internet via a router in the same LAN, Then all access to www.example.com, because these users share the same extranet IP address, this will cause the server to think that these users are the same user requests, because they are from the same IP address access.
The first step in maintaining application state is to know how to uniquely identify each client. Because only the information that is carried in the request in HTTP can be used to identify the client, it must contain some information that can be used to identify the client's unique identity in the request. Cookies are designed to solve this problem.
Third, cookies
If you look at cookies as an extension of the HTTP protocol, it's much easier to understand, in essence, cookies are an extension of HTTP. There are two HTTP headers that are specifically responsible for setting up and sending cookies, respectively, Set-cookie and cookies. When the server returns an HTTP response message to the client, where it contains the header of Set-cookie, it means that the client establishes a cookie and automatically sends the cookie to the server on subsequent HTTP requests until the cookie expires. If the cookie's lifetime is the entire session, the browser will save the cookie in memory and the cookie will be automatically erased when the browser is closed. Another case is saved on the client's hard drive, the browser is closed, the cookie will not be cleared, the next time you open a browser to access the corresponding website, the cookie will be automatically sent to the server side. The setting of a cookie and the sending process are divided into the following four steps:
1. The client sends an HTTP request to the server side
2. Server-side sends an HTTP response to the client, which contains the Set-cookie header
3. The client sends an HTTP request to the server side, which contains the cookie header
4. Server-side sends an HTTP response to the client
This communication process can also be described with the following:
In the cookie header contained in the client's second request, the server-side information that can be used to uniquely identify the client is provided. At this point, the server side can also determine whether the client has enabled cookies. Although the user may suddenly disable the use of cookies in the course of interacting with the application, this situation is largely unlikely to occur, so it can be considered without consideration, which in practice proves to be right.
Iv. Get and post data
In addition to cookies, the client can also include the data sent to the server in the requested URL, such as the requested parameters or the requested path. Let's look at an example:
Copy the Code code as follows:
Get/index.php?foo=bar http/1.1
Host:example.org
The above is a regular HTTP GET request sent to the example.org domain corresponding to the Web server under the index.php script, in the index.php script, can be $_get[' foo ' To get the value of the Foo parameter in the corresponding URL, which is ' bar '. Most PHP developers call this data get data, and a few call it query data or URL variables. However, it is important to note that the get data can only be included in the HTTP get type of the request, in the HTTP post type of request may also contain get data, as long as the relevant get data is included in the requested URL, That is, the delivery of the get data is not dependent on the type of the specific request.
Another way the client passes data to the server is to include the data in the content area of the HTTP request. This method requires the type of the request to be post, see the following example:
Copy the Code code 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 script index.php can get the corresponding value bar by calling $_post[' foo '. The developer calls this data the post data, which is known as the way the form submits the request in post.
In a request, you can include both forms of data:
Copy the Code code 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 ways of transmitting data are more stable than using cookies to pass data, because cookies may be disabled, but not when passing data in get and post. We can include PHPSESSID in the URL of the HTTP request, as in the following example:
[Code]
Get/index.php? phpsessid=12345 http/1.1
Host:example.org
Passing the session ID in this way can be as effective as passing the session ID with the cookie header, but the downside is that the developer is expected to attach the session ID to the URL or add it as a hidden field to the form. Unlike cookies, as long as the server side instructs the client to create a cookie successfully, the client will automatically pass the corresponding non-period cookie to the server in subsequent requests. Of course, PHP can automatically append the session ID to the URL and the hidden field in the form after Session.use_trans_sid is turned on, but this option is not recommended because of a security issue. In this case, it is easy to leak the session ID, such as some users will bookmark a URL or share a URL, then the session ID is exposed, join this session ID has not expired, there is a certain security problem exists, unless the server side, In addition to the session ID, there are other ways to verify the legality of the user!
Although the session ID is passed as a post, it is much safer relative to get. However, the disadvantage of this approach is that it is more cumbersome, because it is obviously not appropriate to compare all requests to post requests in your application.
V. Management of the session
Until now, I have only discussed how to maintain the state of the application, simply involving the relationship between if the request is kept. Next, I illustrate the use of more technical –session in the actual management. When it comes to session management, it is not just maintaining the state between requests, but also maintaining the data that is used for each specific user during the session. We often call this data the session data because it is associated with a particular user and the server. If you use the PHP built-in session management mechanism, then the session data is generally stored in the/TMP server-side folder, and the session data will be automatically saved to the Super array $_session. One of the simplest examples of using a session is to pass the relevant session data from one page (Note: The session ID is actually passed) to another page. Here is a demonstration of this example in example code 1, start.php:
Sample Code 1–start.php
Copy the Code code as follows:
continue.php
If the user clicks on the link in start.php to access continue.php, then the value ' bar ' defined in start.php can be obtained by $_session[' foo ' in continue.php. Look at the following example code 2:
Sample Code 2–continue.php
Copy the Code code as follows:
is not very simple, but I would like to point out that if you really write the code, it means that you do not have a very thorough understanding of the implementation mechanism of the session in the bottom of PHP. Without knowing how much PHP has done to you automatically, you'll find that if the program goes wrong, the code will be hard to debug, and in fact, there's no security at all.
VI. security issues in session
A lot of developers have been thinking that PHP built-in session management mechanism is a certain security, can be used to attack the general session of the defense. In fact, this is a misconception that the PHP team only implements a convenient and efficient mechanism. Specific security measures should be implemented by the application development team. Just like the opening talk, there is no best solution, only the one that suits you best.
Now, let's look at a more general attack on the session:
1: The user accesses http://www.example.org and logs on.
2.example.org server settings indicate client settings related cookie–phpsessid=12345
3. The attacker accesses http://www.example.org/at this time and carries the corresponding cookie–phpsessid=12345 in the request
4. In this case, the server mistakenly treats the attacker as a legitimate user because the Example.orge server uses PHPSESSID to identify the corresponding user.
For a description of the entire process, see the following example diagram:
Of course this kind of attack, the precondition is that the attacker must be fixed by some means, hijack or guess the phpsessid of a legitimate user. Although this may seem difficult, it is not an impossible thing.
Vii. Strengthening of security
There are many techniques that can be used to enhance the security of the session, the main idea is to make the verification process for legitimate users, the simpler the better, and then for the attackers, the more complex the step, the better. Of course, this seems to be more difficult to balance, depending on the specific design of your application to make decisions.
The simplest people http/1.1 requests include the request line and some host headers:
Copy the Code code as follows:
get/http/1.1
Host:example.org
If the client passes the associated session identifier via PHPSESSID, the PHPSESSID can be placed in the cookie header for delivery:
Copy the Code code as follows:
get/http/1.1
Host:example.org
cookie:phpsessid=12345
Similarly, the client can also place the session identifier in the requested URL for delivery.
Copy the Code code as follows:
GET/? phpsessid=12345
http/1.1host:example.org
Of course, the session identifier can also be included in the post data, but it has an impact on the user experience, so this approach is rarely used.
Because information from TCP/IP is not necessarily fully trusted, it is not appropriate for Web developers to use the information in TCP/IP to enhance security. However, an attacker would also have to provide a unique identifier for a legitimate user to enter the system disguised as a legitimate user. 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 is best to implement both.
PHP will automatically generate a random session ID, basically it is impossible to guess, so this aspect of security is still a certain guarantee. However, it is quite difficult to prevent an attacker from acquiring a valid session ID, which is basically not what the developer can control.
In fact, in many cases it can lead to the disclosure of Session IDs. For example, if the session ID is passed through the get data, it is possible to expose this sensitive identity information. Because, some users may be the link with the session ID cached, collected or sent in the message content. Cookies are a relatively safe mechanism, but users can disable cookies in the client! In some versions of IE, there are more serious security vulnerabilities, the more famous is the disclosure of cookies to some of the evil sites have security risks.
Therefore, as a developer, it is certain that the session ID can not be guessed, but it is still possible for the attacker to use some method to obtain. Therefore, some additional security measures must be taken to prevent such situations from occurring in your application.
In fact, a standard HTTP request contains some optional headers in addition to the headers that must be included in the host. For example, look at one of the following requests:
Copy the Code code as follows:
get/http/1.1
Host:example.org
cookie:phpsessid=12345
user-agent:mozilla/5.0 (Macintosh; U Intel Mac OS X; En-us; rv:1.8.1.1) gecko/20061204 firefox/2.0.0.1
accept:text/html;q=0.9, */*;q=0.1
Accept-charset:iso-8859-1, utf-8;q=0.66, *;q=0.66
Accept-language:en
We can see that in one of the above request examples are four additional headers, namely User-agent, Accept, Accept-charset, and Accept-language. Because these headers are not required, it is not advisable to rely entirely on them to play a role in your application. However, if a user's browser does send these headers to the server, then it is certain that the same user will be carrying the headers in the request that the next person is sending through the same browser. Of course, there are very few special cases that can happen. If the above example is a request made by a user who has a current session with the server, consider one of the following requests:
Copy the Code code 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 requested cookie header, 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 were made by the same user?
In this case, found that the browser's head changed, but not sure whether this is a request from the attacker, the better measure is to pop up a request to enter a password input box for the user input, so that the user experience will not be very significant, but also very effective to prevent attacks.
Of course, you can include the code that checks the User-agent header in your system, similar to the code in Example 3:
Example Code 3:
Copy the Code code as follows:
Of course, you must first, at the first request, initialize the session, encrypt the user agent information with the MD5 algorithm and save it in the session, similar to the code in example 4 below:
Example Code 4:
Copy the Code code as follows:
Although it is not necessary to use MD5 to encrypt this user-agent information, but in this way there is no need to filter this $_server[' http_user_agent ' data again. Otherwise, the data must be filtered before using this data, because any data from the client is untrusted and must be noted.
After you have checked the User-agent client header information, as an attacker, you must complete two steps to hijack a session:
1. Get a valid session ID
2. Contains an identical user-agent head in a forged request
You might say that an attacker can get a valid session ID, so it is not difficult to forge an identical user-agent at his level. Yes, but we can say that this has at least added some trouble to him and, to a certain extent, increased the security of the session mechanism.
You should also be able to think of, since we can check user-agent this head to enhance security, then we may be able to use some other header information, put them together to generate an encrypted token, and let the client in subsequent requests to carry this token! In this case, it is almost impossible for an attacker to guess how such a token was generated. This is like you pay by credit card in the supermarket, one you must have a credit card (like session ID), and you must also enter a payment password (like token), which has both of these in accordance with the circumstances, you can successfully enter the account payment. Look at the following section of code:
Copy the Code code as follows:
Note: Accept this header should not be used to generate tokens, because some browsers will automatically change the header when the user refreshes the browser.
With this very hard-to-guess token added to your verification mechanism, security can be greatly improved. If the token is passed in the same way as the session ID, in which case an attacker would have to complete the necessary 3 steps to hijack the user's session:
1. Get a valid session ID
2. Add the same user-agent header to the request, using and generating tokens
3. Carry the token of the attacker in the request
4. There's a problem here. If the session ID and token are passed through the get data, the token can also be obtained for an attacker who has access to the session ID. Therefore, the more secure way should be to use two different data transfer methods to pass the session ID and token. For example, pass the session ID through a cookie and pass the token through the get data. Therefore, if an attacker obtains this unique user identity by some means, it is unlikely that the token will be readily available at the same time, and it is relatively safe.
There are also a number of techniques that can be used to enhance the security of your session mechanism. I hope that you understand the internal nature of the session, you can design a suitable application system validation mechanism, thus greatly improve the security of the system. After all, you are one of the developers who are most familiar with the system you are developing today, and can implement some unique, additional security measures based on the actual situation.
Viii. Summary
The above is just a general description of the working mechanism of the session, as well as a simple explanation of some security measures. Keep in mind, however, that the above methods are able to enhance security, not to be able to completely protect your system, hoping that the reader will investigate the relevant content. In this research process, I believe that you will learn a very practical use of the value of the program.