<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Simon+Waters</id>
		<title>OWASP - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.owasp.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Simon+Waters"/>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php/Special:Contributions/Simon_Waters"/>
		<updated>2026-04-23T23:35:59Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.2</generator>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Session_Management_Cheat_Sheet&amp;diff=231494</id>
		<title>Session Management Cheat Sheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Session_Management_Cheat_Sheet&amp;diff=231494"/>
				<updated>2017-07-10T09:27:34Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: s/weak/permissive/ for clarity&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; __NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;width:100%;height:160px;border:0,margin:0;overflow: hidden;&amp;quot;&amp;gt;[[File:Cheatsheets-header.jpg|link=]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;padding: 0;margin:0;margin-top:10px;text-align:left;&amp;quot; |-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; style=&amp;quot;border-right: 1px dotted gray;padding-right:25px;&amp;quot; |&lt;br /&gt;
Last revision (mm/dd/yy): '''{{REVISIONMONTH}}/{{REVISIONDAY}}/{{REVISIONYEAR}}''' &lt;br /&gt;
= Introduction  =&lt;br /&gt;
 __TOC__{{TOC hidden}}&lt;br /&gt;
&lt;br /&gt;
'''Web Authentication, Session Management, and Access Control''' &lt;br /&gt;
&lt;br /&gt;
A web session is a sequence of network HTTP request and response transactions associated to the same user. Modern and complex web applications require the retaining of information or status about each user for the duration of multiple requests. Therefore, sessions provide the ability to establish variables – such as access rights and localization settings – which will apply to each and every interaction a user has with the web application for the duration of the session. &lt;br /&gt;
&lt;br /&gt;
Web applications can create sessions to keep track of anonymous users after the very first user request. An example would be maintaining the user language preference. Additionally, web applications will make use of sessions once the user has authenticated. This ensures the ability to identify the user on any subsequent requests as well as being able to apply security access controls, authorized access to the user private data, and to increase the usability of the application. Therefore, current web applications can provide session capabilities both pre and post authentication. &lt;br /&gt;
&lt;br /&gt;
Once an authenticated session has been established, the session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as username and password, passphrases, one-time passwords (OTP), client-based digital certificates, smartcards, or biometrics (such as fingerprint or eye retina). See the OWASP Authentication Cheat Sheet: https://www.owasp.org/index.php/Authentication_Cheat_Sheet. &lt;br /&gt;
&lt;br /&gt;
HTTP is a stateless protocol (RFC2616 [5]), where each request and response pair is independent of other web interactions. Therefore, in order to introduce the concept of a session, it is required to implement session management capabilities that link both the authentication and access control (or authorization) modules commonly available in web applications: &lt;br /&gt;
&lt;br /&gt;
[[Image:Session-Management-Diagram Cheat-Sheet.png|center|Session-Management-Diagram Cheat-Sheet.png]] &amp;lt;br&amp;gt; The session ID or token binds the user authentication credentials (in the form of a user session) to the user HTTP traffic and the appropriate access controls enforced by the web application. The complexity of these three components (authentication, session management, and access control) in modern web applications, plus the fact that its implementation and binding resides on the web developer’s hands (as web development framework do not provide strict relationships between these modules), makes the implementation of a secure session management module very challenging. &lt;br /&gt;
&lt;br /&gt;
The disclosure, capture, prediction, brute force, or fixation of the session ID will lead to session hijacking (or sidejacking) attacks, where an attacker is able to fully impersonate a victim user in the web application. Attackers can perform two types of session hijacking attacks, targeted or generic. In a targeted attack, the attacker’s goal is to impersonate a specific (or privileged) web application victim user. For  generic attacks, the attacker’s goal is to impersonate (or get access as) any valid or legitimate user in the web application. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session ID Properties  =&lt;br /&gt;
&lt;br /&gt;
In order to keep the authenticated state and track the users progress within the web application, applications provide users with a session identifier (session ID or token) that is assigned at session creation time, and is shared and exchanged by the user and the web application for the duration of the session (it is sent on every HTTP request). The session ID is a “name=value” pair. &lt;br /&gt;
&lt;br /&gt;
With the goal of implementing secure session IDs, the generation of identifiers (IDs or tokens) must meet the following properties: &lt;br /&gt;
&lt;br /&gt;
== Session ID Name Fingerprinting  ==&lt;br /&gt;
&lt;br /&gt;
The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID. &lt;br /&gt;
&lt;br /&gt;
The session ID names used by the most common web application development frameworks can be easily fingerprinted [0], such as PHPSESSID (PHP), JSESSIONID (J2EE), CFID &amp;amp;amp; CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Therefore, the session ID name can disclose the technologies and programming languages used by the web application. &lt;br /&gt;
&lt;br /&gt;
It is recommended to change the default session ID name of the web development framework to a generic name, such as “id”. &lt;br /&gt;
&lt;br /&gt;
== Session ID Length  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be long enough to prevent brute force attacks, where an attacker can go through the whole range of ID values and verify the existence of valid sessions. &lt;br /&gt;
&lt;br /&gt;
The session ID length must be at least 128 bits (16 bytes).&lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': The session ID length of 128 bits is provided as a reference based on the assumptions made on the next section &amp;quot;Session ID Entropy&amp;quot;. However, this number should not be considered as an absolute minimum value, as other implementation factors might influence its strength. For example, there are well-known implementations, such as Microsoft ASP.NET, making use of 120-bit random numbers for its session IDs (represented by 20-character strings [10]) that can provide a very good effective entropy, and as a result, can be considered long enough to avoid guessing or brute force attacks.&lt;br /&gt;
&lt;br /&gt;
== Session ID Entropy  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict the ID of a valid session through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used. &lt;br /&gt;
&lt;br /&gt;
The session ID value must provide at least 64 bits of entropy (if a good PRNG is used, this value is estimated to be half the length of the session ID).&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': The session ID entropy is really affected by other external and difficult to measure factors, such as the number of concurrent active sessions the web application commonly has, the absolute session expiration timeout, the amount of session ID guesses per second the attacker can make and the target web application can support, etc [2]. If a session ID with an entropy of 64 bits is used, it will take an attacker at least 292 years to successfully guess a valid session ID, assuming the attacker can try 10,000 guesses per second with 100,000 valid simultaneous sessions available in the web application [2]. &lt;br /&gt;
&lt;br /&gt;
== Session ID Content (or Value)  ==&lt;br /&gt;
&lt;br /&gt;
The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application. &lt;br /&gt;
&lt;br /&gt;
The session ID must simply be an identifier on the client side, and its value must never include sensitive information (or PII). The meaning and business or application logic associated to the session ID must be stored on the server side, and specifically, in session objects or in a session management database or repository. The stored information can include the client IP address, User-Agent, e-mail, username, user ID, role, privilege level, access rights, language preferences, account ID, current state, last login, session timeouts, and other internal session details. If the session objects and properties contain sensitive information, such as credit card numbers, it is required to duly encrypt and protect the session management repository. &lt;br /&gt;
&lt;br /&gt;
It is recommended to create cryptographically strong session IDs through the usage of cryptographic hash functions such as SHA1 (160 bits). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Management Implementation  =&lt;br /&gt;
&lt;br /&gt;
The session management implementation defines the exchange mechanism that will be used between the user and the web application to share and continuously exchange the session ID. There are multiple mechanisms available in HTTP to maintain session state within web applications, such as cookies (standard HTTP header), URL parameters (URL rewriting – RFC 2396), URL arguments on GET requests, body arguments on POST requests, such as hidden form fields (HTML forms), or proprietary HTTP headers. &lt;br /&gt;
&lt;br /&gt;
The preferred session ID exchange mechanism should allow defining advanced token properties, such as the token expiration date and time, or granular usage constraints. This is one of the reasons why cookies (RFCs 2109 &amp;amp;amp; 2965 &amp;amp;amp; 6265 [1]) are one of the most extensively used session ID exchange mechanisms, offering advanced capabilities not available in other methods. &lt;br /&gt;
&lt;br /&gt;
The usage of specific session ID exchange mechanisms, such as those where the ID is included in the URL, might disclose the session ID (in web links and logs, web browser history and bookmarks, the Referer header or search engines), as well as facilitate other attacks, such as the manipulation of the ID or session fixation attacks [3]. &lt;br /&gt;
&lt;br /&gt;
== Built-in Session Management Implementations  ==&lt;br /&gt;
&lt;br /&gt;
Web development frameworks, such as J2EE, ASP .NET, PHP, and others, provide their own session management features and associated implementation. It is recommended to use these built-in frameworks versus building a home made one from scratch, as they are used worldwide on multiple web environments and have been tested by the web application security and development communities over time. &lt;br /&gt;
&lt;br /&gt;
However, be advised that these frameworks have also presented vulnerabilities and weaknesses in the past, so it is always recommended to use the latest version available, that potentially fixes all the well-known vulnerabilities, as well as review and change the default configuration to enhance its security by following the recommendations described along this document. &lt;br /&gt;
&lt;br /&gt;
The storage capabilities or repository used by the session management mechanism to temporarily save the session IDs must be secure, protecting the session IDs against local or remote accidental disclosure or unauthorized access. &lt;br /&gt;
&lt;br /&gt;
== Used vs. Accepted Session ID Exchange Mechanisms  ==&lt;br /&gt;
&lt;br /&gt;
A web application should make use of cookies for session ID exchange management. If a user submits a session ID through a different exchange mechanism, such as a URL parameter, the web application should avoid accepting it as part of a defensive strategy to stop session fixation.&lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': Even if a web application makes use of cookies as its default session ID exchange mechanism, it might accept other exchange mechanisms too. It is therefore required to confirm via thorough testing all the different mechanisms currently accepted by the web application when processing and managing session IDs, and limit the accepted session ID tracking mechanisms to just cookies. In the past, some web applications used URL parameters, or even switched from cookies to URL parameters (via automatic URL rewriting), if certain conditions are met (for example, the identification of web clients without support for cookies or not accepting cookies due to user privacy concerns).&lt;br /&gt;
&lt;br /&gt;
== Transport Layer Security  ==&lt;br /&gt;
&lt;br /&gt;
In order to protect the session ID exchange from active eavesdropping and passive disclosure in the network traffic, it is mandatory to use an encrypted HTTPS (SSL/TLS) connection for the entire web session, not only for the authentication process where the user credentials are exchanged. &lt;br /&gt;
&lt;br /&gt;
Additionally, the “Secure” cookie attribute (see below) must be used to ensure the session ID is only exchanged through an encrypted channel. The usage of an encrypted communication channel also protects the session against some session fixation attacks where the attacker is able to intercept and manipulate the web traffic to inject (or fix) the session ID on the victims web browser [4]. &lt;br /&gt;
&lt;br /&gt;
The following set of HTTPS (SSL/TLS) best practices are focused on protecting the session ID (specifically when cookies are used) and helping with the integration of HTTPS within the web application: &lt;br /&gt;
&lt;br /&gt;
*Web applications should never switch a given session from HTTP to HTTPS, or viceversa, as this will disclose the session ID in the clear through the network. &lt;br /&gt;
*Web applications should not mix encrypted and unencrypted contents (HTML pages, images, CSS, Javascript files, etc) on the same host (or even domain - see the “domain” cookie attribute), as the request of any web object over an unencrypted channel might disclose the session ID. &lt;br /&gt;
*Web applications, in general, should not offer public unencrypted contents and private encrypted contents from the same host. It is recommended to instead use two different hosts, such as www.example.com over HTTP (unencrypted) for the public contents, and secure.example.com over HTTPS (encrypted) for the private and sensitive contents (where sessions exist). The former host only has port TCP/80 open, while the later only has port TCP/443 open. &lt;br /&gt;
*Web applications should avoid the extremely common HTTP to HTTPS redirection on the home page (using a 30x HTTP response), as this single unprotected HTTP request/response exchange can be used by an attacker to gather (or fix) a valid session ID.&lt;br /&gt;
* Web applications should make use of “HTTP Strict Transport Security (HSTS)” (previously called STS) to enforce HTTPS connections.&lt;br /&gt;
&lt;br /&gt;
See the OWASP Transport Layer Protection Cheat Sheet: https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet. &lt;br /&gt;
&lt;br /&gt;
It is important to emphasize that SSL/TLS (HTTPS) does not protect against session ID prediction, brute force, client-side tampering or fixation. Yet, session ID disclosure and capture from the network traffic is one of the most prevalent attack vectors even today. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Cookies  =&lt;br /&gt;
&lt;br /&gt;
The session ID exchange mechanism based on cookies provides multiple security features in the form of cookie attributes that can be used to protect the exchange of the session ID: &lt;br /&gt;
&lt;br /&gt;
== Secure Attribute  ==&lt;br /&gt;
&lt;br /&gt;
The “Secure” cookie attribute instructs web browsers to only send the cookie through an encrypted HTTPS (SSL/TLS) connection. This session protection mechanism is mandatory to prevent the disclosure of the session ID through MitM (Man-in-the-Middle) attacks. It ensures that an attacker cannot simply capture the session ID from web browser traffic. &lt;br /&gt;
&lt;br /&gt;
Forcing the web application to only use HTTPS for its communication (even when port TCP/80, HTTP, is closed in the web application host) does not protect against session ID disclosure if the “Secure” cookie has not been set - the web browser can be deceived to disclose the session ID over an unencrypted HTTP connection. The attacker can intercept and manipulate the victim user traffic and inject an HTTP unencrypted reference to the web application that will force the web browser to submit the session ID in the clear.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/SecureFlag SecureFlag]&lt;br /&gt;
&lt;br /&gt;
== HttpOnly Attribute  ==&lt;br /&gt;
&lt;br /&gt;
The “HttpOnly” cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) an ability to access the cookies via the DOM document.cookie object. This session ID protection is mandatory to prevent session ID stealing through XSS attacks. &lt;br /&gt;
&lt;br /&gt;
See the OWASP XSS Prevention Cheat Sheet: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/HttpOnly HttpOnly]&lt;br /&gt;
&lt;br /&gt;
== SameSite Attribute ==&lt;br /&gt;
SameSite allows a server define a cookie attribute making it impossible to the browser send this cookie along with cross-site requests. The main goal is mitigate the risk of cross-origin information leakage, and provides some protection against cross-site request forgery attacks.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/SameSite SameSite]&lt;br /&gt;
&lt;br /&gt;
== Domain and Path Attributes  ==&lt;br /&gt;
&lt;br /&gt;
The “Domain” cookie attribute instructs web browsers to only send the cookie to the specified domain and all subdomains. If the attribute is not set, by default the cookie will only be sent to the origin server. The “Path” cookie attribute instructs web browsers to only send the cookie to the specified directory or subdirectories (or paths or resources) within the web application. If the attribute is not set, by default the cookie will only be sent for the directory (or path) of the resource requested and setting the cookie. &lt;br /&gt;
&lt;br /&gt;
It is recommended to use a narrow or restricted scope for these two attributes. In this way, the “Domain” attribute should not be set (restricting the cookie just to the origin server) and the “Path” attribute should be set as restrictive as possible to the web application path that makes use of the session ID. &lt;br /&gt;
&lt;br /&gt;
Setting the “Domain” attribute to a too permissive value, such as “example.com” allows an attacker to launch attacks on the session IDs between different hosts and web applications belonging to the same domain, known as cross-subdomain cookies. For example, vulnerabilities in www.example.com might allow an attacker to get access to the session IDs from secure.example.com. &lt;br /&gt;
&lt;br /&gt;
Additionally, it is recommended not to mix web applications of different security levels on the same domain. Vulnerabilities in one of the web applications would allow an attacker to set the session ID for a different web application on the same domain by using a permissive “Domain” attribute (such as “example.com”) which is a technique that can be used in session fixation attacks [4]. &lt;br /&gt;
&lt;br /&gt;
Although the “Path” attribute allows the isolation of session IDs between different web applications using different paths on the same host, it is highly recommended not to run different web applications (especially from different security levels or scopes) on the same host. Other methods can be used by these applications to access the session IDs, such as the “document.cookie” object. Also, any web application can set cookies for any path on that host. &lt;br /&gt;
&lt;br /&gt;
Cookies are vulnerable to DNS spoofing/hijacking/poisoning attacks, where an attacker can manipulate the DNS resolution to force the web browser to disclose the session ID for a given host or domain. &lt;br /&gt;
&lt;br /&gt;
== Expire and Max-Age Attributes  ==&lt;br /&gt;
&lt;br /&gt;
Session management mechanisms based on cookies can make use of two types of cookies, non-persistent (or session) cookies, and persistent cookies. If a cookie presents the “Max-Age” (that has preference over “Expires”) or “Expires” attributes, it will be considered a persistent cookie and will be stored on disk by the web browser based until the expiration time. Typically, session management capabilities to track users after authentication make use of non-persistent cookies. This forces the session to disappear from the client if the current web browser instance is closed. Therefore, it is highly recommended to use non-persistent cookies for session management purposes, so that the session ID does not remain on the web client cache for long periods of time, from where an attacker can obtain it. &lt;br /&gt;
&lt;br /&gt;
* Ensure that sensitive information is not comprised, by ensuring that sensitive information is not persistent / encrypting / stored on a need basis for the duration of the need&lt;br /&gt;
&lt;br /&gt;
* Ensure that unauthorized activities cannot take place via cookie manipulation&lt;br /&gt;
&lt;br /&gt;
* Ensure secure flag is set to prevent accidental transmission over “the wire” in a non-secure manner&lt;br /&gt;
&lt;br /&gt;
* Determine if all state transitions in the application code properly check for the cookies and enforce their use&lt;br /&gt;
&lt;br /&gt;
* Ensure entire cookie should be encrypted if sensitive data is persisted in the cookie&lt;br /&gt;
&lt;br /&gt;
* Define all cookies being used by the application, their name and why they are needed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Session ID Life Cycle  =&lt;br /&gt;
&lt;br /&gt;
== Session ID Generation and Verification: Permissive and Strict Session Management  ==&lt;br /&gt;
&lt;br /&gt;
There are two types of session management mechanisms for web applications, permissive and strict, related to session fixation vulnerabilities. The permissive mechanism allow the web application to initially accept any session ID value set by the user as valid, creating a new session for it, while the strict mechanism enforces that the web application will only accept session ID values that have been previously generated by the web application. &lt;br /&gt;
&lt;br /&gt;
The session tokens should be handled by the web server if possible or generated via a cryptographically secure random number generator.&lt;br /&gt;
&lt;br /&gt;
Although the most common mechanism in use today is the strict one (more secure, [https://wiki.php.net/rfc/session-use-strict-mode PHP defaults to permissive]). Developers must ensure that the web application does not use a permissive mechanism under certain circumstances. Web applications should never accept a session ID they have never generated, and in case of receiving one, they should generate and offer the user a new valid session ID. Additionally, this scenario should be detected as a suspicious activity and an alert should be generated. &lt;br /&gt;
&lt;br /&gt;
== Manage Session ID as Any Other User Input  ==&lt;br /&gt;
&lt;br /&gt;
Session IDs must be considered untrusted, as any other user input processed by the web application, and they must be thoroughly validated and verified. Depending on the session management mechanism used, the session ID will be received in a GET or POST parameter, in the URL or in an HTTP header (e.g. cookies). If web applications do not validate and filter out invalid session ID values before processing them, they can potentially be used to exploit other web vulnerabilities, such as SQL injection if the session IDs are stored on a relational database, or persistent XSS if the session IDs are stored and reflected back afterwards by the web application. &lt;br /&gt;
&lt;br /&gt;
== Renew the Session ID After Any Privilege Level Change  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be renewed or regenerated by the web application after any privilege level change within the associated user session. The most common scenario where the session ID regeneration is mandatory is during the authentication process, as the privilege level of the user changes from the unauthenticated (or anonymous) state to the authenticated state. Other common scenarios must also be considered, such as password changes, permission changes or switching from a regular user role to an administrator role within the web application. For all these web application critical pages, previous session IDs have to be ignored, a new session ID must be assigned to every new request received for the critical resource, and the old or previous session ID must be destroyed. &lt;br /&gt;
&lt;br /&gt;
The most common web development frameworks provide session functions and methods to renew the session ID, such as “request.getSession(true) &amp;amp;amp; HttpSession.invalidate()” (J2EE), “Session.Abandon() &amp;amp;amp; Response.Cookies.Add(new…)“ (ASP .NET), or “session_start() &amp;amp;amp; session_regenerate_id(true)” (PHP). &lt;br /&gt;
&lt;br /&gt;
The session ID regeneration is mandatory to prevent session fixation attacks [3], where an attacker sets the session ID on the victims user web browser instead of gathering the victims session ID, as in most of the other session-based attacks, and independently of using HTTP or HTTPS. This protection mitigates the impact of other web-based vulnerabilities that can also be used to launch session fixation attacks, such as HTTP response splitting or XSS [4]. &lt;br /&gt;
&lt;br /&gt;
A complementary recommendation is to use a different session ID or token name (or set of session IDs) pre and post authentication, so that the web application can keep track of anonymous users and authenticated users without the risk of exposing or binding the user session between both states. &lt;br /&gt;
&lt;br /&gt;
== Considerations When Using Multiple Cookies  ==&lt;br /&gt;
&lt;br /&gt;
If the web application uses cookies as the session ID exchange mechanism, and multiple cookies are set for a given session, the web application must verify all cookies (and enforce relationships between them) before allowing access to the user session. &lt;br /&gt;
&lt;br /&gt;
It is very common for web applications to set a user cookie pre-authentication over HTTP to keep track of unauthenticated (or anonymous) users. Once the user authenticates in the web application, a new post-authentication secure cookie is set over HTTPS, and a binding between both cookies and the user session is established. If the web application does not verify both cookies for authenticated sessions, an attacker can make use of the pre-authentication unprotected cookie to get access to the authenticated user session [4]. &lt;br /&gt;
&lt;br /&gt;
Web applications should try to avoid the same cookie name for different paths or domain scopes within the same web application, as this increases the complexity of the solution and potentially introduces scoping issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Session Expiration  =&lt;br /&gt;
&lt;br /&gt;
In order to minimize the time period an attacker can launch attacks over active sessions and hijack them, it is mandatory to set expiration timeouts for every session, establishing the amount of time a session will remain active. Insufficient session expiration by the web application increases the exposure of other session-based attacks, as for the attacker to be able to reuse a valid session ID and hijack the associated session, it must still be active. &lt;br /&gt;
&lt;br /&gt;
The shorter the session interval is, the lesser the time an attacker has to use the valid session ID. The session expiration timeout values must be set accordingly with the purpose and nature of the web application, and balance security and usability, so that the user can comfortably complete the operations within the web application without his session frequently expiring. Both the idle and absolute timeout values are highly dependent on how critical the web application and its data are. Common idle timeouts ranges are 2-5 minutes for high-value applications and 15- 30 minutes for low risk applications. &lt;br /&gt;
&lt;br /&gt;
When a session expires, the web application must take active actions to invalidate the session on both sides, client and server. The latter is the most relevant and mandatory from a security perspective. &lt;br /&gt;
&lt;br /&gt;
For most session exchange mechanisms, client side actions to invalidate the session ID are based on clearing out the token value. For example, to invalidate a cookie it is recommended to provide an empty (or invalid) value for the session ID, and set the “Expires” (or “Max-Age”) attribute to a date from the past (in case a persistent cookie is being used): &lt;br /&gt;
&amp;lt;pre&amp;gt;Set-Cookie: id=; Expires=Friday, 17-May-03 18:45:00 GMT &amp;lt;/pre&amp;gt; &lt;br /&gt;
In order to close and invalidate the session on the server side, it is mandatory for the web application to take active actions when the session expires, or the user actively logs out, by using the functions and methods offered by the session management mechanisms, such as “HttpSession.invalidate()” (J2EE), “Session.Abandon()“ (ASP .NET) or “session_destroy()/unset()“ (PHP). &lt;br /&gt;
&lt;br /&gt;
== Automatic Session Expiration  ==&lt;br /&gt;
&lt;br /&gt;
=== Idle Timeout  ===&lt;br /&gt;
&lt;br /&gt;
All sessions should implement an idle or inactivity timeout. This timeout defines the amount of time a session will remain active in case there is no activity in the session, closing and invalidating the session upon the defined idle period since the last HTTP request received by the web application for a given session ID. &lt;br /&gt;
&lt;br /&gt;
The idle timeout limits the chances an attacker has to guess and use a valid session ID from another user. However, if the attacker is able to hijack a given session, the idle timeout does not limit the attacker’s actions, as he can generate activity on the session periodically to keep the session active for longer periods of time. &lt;br /&gt;
&lt;br /&gt;
Session timeout management and expiration must be enforced server-side. If the client is used to enforce the session timeout, for example using the session token or other client parameters to track time references (e.g. number of minutes since login time), an attacker could manipulate these to extend the session duration. &lt;br /&gt;
&lt;br /&gt;
=== Absolute Timeout  ===&lt;br /&gt;
&lt;br /&gt;
All sessions should implement an absolute timeout, regardless of session activity. This timeout defines the maximum amount of time a session can be active, closing and invalidating the session upon the defined absolute period since the given session was initially created by the web application. After invalidating the session, the user is forced to (re)authenticate again in the web application and establish a new session. &lt;br /&gt;
&lt;br /&gt;
The absolute session limits the amount of time an attacker can use a hijacked session and impersonate the victim user. &lt;br /&gt;
&lt;br /&gt;
=== Renewal Timeout  ===&lt;br /&gt;
&lt;br /&gt;
Alternatively, the web application can implement an additional renewal timeout after which the session ID is automatically renewed, in the middle of the user session, and independently of the session activity and, therefore, of the idle timeout. &lt;br /&gt;
&lt;br /&gt;
After a specific amount of time since the session was initially created, the web application can regenerate a new ID for the user session and try to set it, or renew it, on the client. The previous session ID value would still be valid for some time, accommodating a safety interval, before the client is aware of the new ID and starts using it. At that time, when the client switches to the new ID inside the current session, the application invalidates the previous ID.&lt;br /&gt;
&lt;br /&gt;
This scenario minimizes the amount of time a given session ID value, potentially obtained by an attacker, can be reused to hijack the user session, even when the victim user session is still active. The user session remains alive and open on the legitimate client, although its associated session ID value is transparently renewed periodically during the session duration, every time the renewal timeout expires. Therefore, the renewal timeout complements the idle and absolute timeouts, specially when the absolute timeout value extends significantly over time (e.g. it is an application requirement to keep the user sessions opened for long periods of time).&lt;br /&gt;
&lt;br /&gt;
Depending of the implementation, potentially there could be a race condition where the attacker with a still valid previous session ID sends a request before the victim user, right after the renewal timeout has just expired, and obtains first the value for the renewed session ID. At least in this scenario, the victim user might be aware of the attack as her session will be suddenly terminated because her associated session ID is not valid anymore.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Manual Session Expiration  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should provide mechanisms that allow security aware users to actively close their session once they have finished using the web application. &lt;br /&gt;
&lt;br /&gt;
=== Logout Button  ===&lt;br /&gt;
&lt;br /&gt;
Web applications must provide a visible an easily accessible logout (logoff, exit, or close session) button that is available on the web application header or menu and reachable from every web application resource and page, so that the user can manually close the session at any time. As described [[Session_Management_Cheat_Sheet#Session_Expiration|above]], the web application must invalidate the session at least on server side.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''': Unfortunately, not all web applications facilitate users to close their current session. Thus, client-side enhancements such as the PopUp LogOut Firefox add-on [9] allow conscientious users to protect their sessions by helping to close them diligently.&lt;br /&gt;
&lt;br /&gt;
== Web Content Caching  ==&lt;br /&gt;
&lt;br /&gt;
Even after the session has been closed, it might be possible to access the private or sensitive data exchanged within the session through the web browser cache. Therefore, web applications must use restrictive cache directives for all the web traffic exchanged through HTTP and HTTPS, such as the “Cache-Control: no-cache,no-store” and “Pragma: no-cache” HTTP headers [5], and/or equivalent META tags on all or (at least) sensitive web pages. &lt;br /&gt;
&lt;br /&gt;
Independently of the cache policy defined by the web application, if caching web application contents is allowed, the session IDs must never be cached, so it is highly recommended to use the “Cache-Control: no-cache=&amp;quot;Set-Cookie, Set-Cookie2&amp;quot;” directive, to allow web clients to cache everything except the session ID. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Additional Client-Side Defenses for Session Management  =&lt;br /&gt;
&lt;br /&gt;
Web applications can complement the previously described session management defenses with additional countermeasures on the client side. Client-side protections, typically in the form of JavaScript checks and verifications, are not bullet proof and can easily be defeated by a skilled attacker, but can introduce another layer of defense that has to be bypassed by intruders. &lt;br /&gt;
&lt;br /&gt;
== Initial Login Timeout  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code in the login page to evaluate and measure the amount of time since the page was loaded and a session ID was granted. If a login attempt is tried after a specific amount of time, the client code can notify the user that the maximum amount of time to log in has passed and reload the login page, hence retrieving a new session ID. &lt;br /&gt;
&lt;br /&gt;
This extra protection mechanism tries to force the renewal of the session ID pre-authentication, avoiding scenarios where a previously used (or manually set) session ID is reused by the next victim using the same computer, for example, in session fixation attacks. &lt;br /&gt;
&lt;br /&gt;
== Force Session Logout On Web Browser Window Close Events  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code to capture all the web browser tab or window close (or even back) events and take the appropriate actions to close the current session before closing the web browser, emulating that the user has manually closed the session via the logout button. &lt;br /&gt;
&lt;br /&gt;
== Disable Web Browser Cross-Tab Sessions  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code once the user has logged in and a session has been established to force the user to re-authenticate if a new web browser tab or window is opened against the same web application. The web application does not want to allow multiple web browser tabs or windows to share the same session. Therefore, the application tries to force the web browser to not share the same session ID simultaneously between them. &lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': This mechanism cannot be implemented if the session ID is exchanged through cookies, as cookies are shared by all web browser tabs/windows.&amp;amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
== Automatic Client Logout ==&lt;br /&gt;
&lt;br /&gt;
JavaScript code can be used by the web application in all (or critical) pages to automatically logout client sessions after the idle timeout expires, for example, by redirecting the user to the logout page (the same resource used by the logout button mentioned previously). &lt;br /&gt;
&lt;br /&gt;
The benefit of enhancing the server-side idle timeout functionality with client-side code is that the user can see that the session has finished due to inactivity, or even can be notified in advance that the session is about to expire through a count down timer and warning messages. This user-friendly approach helps to avoid loss of work in web pages that require extensive input data due to server-side silently expired sessions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Attacks Detection  =&lt;br /&gt;
&lt;br /&gt;
== Session ID Guessing and Brute Force Detection  ==&lt;br /&gt;
&lt;br /&gt;
If an attacker tries to guess or brute force a valid session ID, he needs to launch multiple sequential requests against the target web application using different session IDs from a single (or set of) IP address(es). Additionally, if an attacker tries to analyze the predictability of the session ID (e.g. using statistical analysis), he needs to launch multiple sequential requests from a single (or set of) IP address(es) against the target web application to gather new valid session IDs. &lt;br /&gt;
&lt;br /&gt;
Web applications must be able to detect both scenarios based on the number of attempts to gather (or use) different session IDs and alert and/or block the offending IP address(es). &lt;br /&gt;
&lt;br /&gt;
== Detecting Session ID Anomalies  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should focus on detecting anomalies associated to the session ID, such as its manipulation. The OWASP AppSensor Project [7] provides a framework and methodology to implement built-in intrusion detection capabilities within web applications focused on the detection of anomalies and unexpected behaviors, in the form of detection points and response actions. Instead of using external protection layers, sometimes the business logic details and advanced intelligence are only available from inside the web application, where it is possible to establish multiple session related detection points, such as when an existing cookie is modified or deleted, a new cookie is added, the session ID from another user is reused, or when the user location or User-Agent changes in the middle of a session. &lt;br /&gt;
&lt;br /&gt;
== Binding the Session ID to Other User Properties  ==&lt;br /&gt;
&lt;br /&gt;
With the goal of detecting (and, in some scenarios, protecting against) user misbehaviors and session hijacking, it is highly recommended to bind the session ID to other user or client properties, such as the client IP address, User-Agent, or client-based digital certificate. If the web application detects any change or anomaly between these different properties in the middle of an established session, this is a very good indicator of session manipulation and hijacking attempts, and this simple fact can be used to alert and/or terminate the suspicious session. &lt;br /&gt;
&lt;br /&gt;
Although these properties cannot be used by web applications to trustingly defend against session attacks, they significantly increase the web application detection (and protection) capabilities. However, a skilled attacker can bypass these controls by reusing the same IP address assigned to the victim user by sharing the same network (very common in NAT environments, like Wi-Fi hotspots) or by using the same outbound web proxy (very common in corporate environments), or by manually modifying his User-Agent to look exactly as the victim users does. &lt;br /&gt;
&lt;br /&gt;
== Logging Sessions Life Cycle: Monitoring Creation, Usage, and Destruction of Session IDs  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should increase their logging capabilities by including information regarding the full life cycle of sessions. In particular, it is recommended to record session related events, such as the creation, renewal, and destruction of session IDs, as well as details about its usage within login and logout operations, privilege level changes within the session, timeout expiration, invalid session activities (when detected), and critical business operations during the session. &lt;br /&gt;
&lt;br /&gt;
The log details might include a timestamp, source IP address, web target resource requested (and involved in a session operation), HTTP headers (including the User-Agent and Referer), GET and POST parameters, error codes and messages, username (or user ID), plus the session ID (cookies, URL, GET, POST…). Sensitive data like the session ID should not be included in the logs in order to protect the session logs against session ID local or remote disclosure or unauthorized access. However, some kind of session-specific information must be logged into order to correlate log entries to specific sessions. It is recommended to log a salted-hash of the session ID instead of the session ID itself in order to allow for session-specific log correlation without exposing the session ID.&lt;br /&gt;
&lt;br /&gt;
In particular, web applications must thoroughly protect administrative interfaces that allow to manage all the current active sessions. Frequently these are used by support personnel to solve session related issues, or even general issues, by impersonating the user and looking at the web application as the user does.&lt;br /&gt;
&lt;br /&gt;
The session logs become one of the main web application intrusion detection data sources, and can also be used by intrusion protection systems to automatically terminate sessions and/or disable user accounts when (one or many) attacks are detected. If active protections are implemented, these defensive actions must be logged too.&lt;br /&gt;
&lt;br /&gt;
== Simultaneous Session Logons  ==&lt;br /&gt;
&lt;br /&gt;
It is the web application design decision to determine if multiple simultaneous logons from the same user are allowed from the same or from different client IP addresses. If the web application does not want to allow simultaneous session logons, it must take effective actions after each new authentication event, implicitly terminating the previously available session, or asking the user (through the old, new or both sessions) about the session that must remain active. &lt;br /&gt;
&lt;br /&gt;
It is recommended for web applications to add user capabilities that allow checking the details of active sessions at any time, monitor and alert the user about concurrent logons, provide user features to remotely terminate sessions manually, and track account activity history (logbook) by recording multiple client details such as IP address, User-Agent, login date and time, idle time, etc. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Management WAF Protections  =&lt;br /&gt;
&lt;br /&gt;
There are situations where the web application source code is not available or cannot be modified, or when the changes required to implement the multiple security recommendations and best practices detailed above imply a full redesign of the web application architecture, and therefore, cannot be easily implemented in the short term. In these scenarios, or to complement the web application defenses, and with the goal of keeping the web application as secure as possible, it is recommended to use external protections such as Web Application Firewalls (WAFs) that can mitigate the session management threats already described. &lt;br /&gt;
&lt;br /&gt;
Web Application Firewalls offer detection and protection capabilities against session based attacks. On the one hand, it is trivial for WAFs to enforce the usage of security attributes on cookies, such as the “Secure” and “HttpOnly” flags, applying basic rewriting rules on the “Set-Cookie” header for all the web application responses that set a new cookie. On the other hand, more advanced capabilities can be implemented to allow the WAF to keep track of sessions, and the corresponding session IDs, and apply all kind of protections against session fixation (by renewing the session ID on the client-side when privilege changes are detected), enforcing sticky sessions (by verifying the relationship between the session ID and other client properties, like the IP address or User-Agent), or managing session expiration (by forcing both the client and the web application to finalize the session). &lt;br /&gt;
&lt;br /&gt;
The open-source ModSecurity WAF, plus the OWASP Core Rule Set [6], provide capabilities to detect and apply security cookie attributes, countermeasures against session fixation attacks, and session tracking features to enforce sticky sessions. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Related Articles  =&lt;br /&gt;
&lt;br /&gt;
[0] '''OWASP Cookies Database. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_Cookies_Database &lt;br /&gt;
&lt;br /&gt;
[1] '''&amp;quot;HTTP State Management Mechanism&amp;quot;. RFC 6265. IETF.''' http://tools.ietf.org/html/rfc6265 &lt;br /&gt;
&lt;br /&gt;
[2] '''Insufficient Session-ID Length. OWASP.''' https://www.owasp.org/index.php/Insufficient_Session-ID_Length &lt;br /&gt;
&lt;br /&gt;
[3] '''Session Fixation. Mitja Kolšek. 2002.''' http://www.acrossecurity.com/papers/session_fixation.pdf &lt;br /&gt;
&lt;br /&gt;
[4] '''&amp;quot;SAP: Session (Fixation) Attacks and Protections (in Web Applications)&amp;quot;. Raul Siles. BlackHat EU 2011.''' &lt;br /&gt;
&lt;br /&gt;
https://media.blackhat.com/bh-eu-11/Raul_Siles/BlackHat_EU_2011_Siles_SAP_Session-Slides.pdf &lt;br /&gt;
&lt;br /&gt;
https://media.blackhat.com/bh-eu-11/Raul_Siles/BlackHat_EU_2011_Siles_SAP_Session-WP.pdf &lt;br /&gt;
&lt;br /&gt;
[5] '''&amp;quot;Hypertext Transfer Protocol -- HTTP/1.1&amp;quot;. RFC2616. IETF.''' http://tools.ietf.org/html/rfc2616 &lt;br /&gt;
&lt;br /&gt;
[6] '''OWASP ModSecurity Core Rule Set (CSR) Project. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project &lt;br /&gt;
&lt;br /&gt;
[7] '''OWASP AppSensor Project. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_AppSensor_Project &lt;br /&gt;
&lt;br /&gt;
[8] '''HttpOnly Session ID in URL and Page Body | Cross Site Scripting''' http://seckb.yehg.net/2012/06/httponly-session-id-in-url-and-page.html&lt;br /&gt;
&lt;br /&gt;
[9] '''PopUp LogOut Firefox add-on''' https://addons.mozilla.org/en-US/firefox/addon/popup-logout/ &amp;amp; http://popuplogout.iniqua.com&lt;br /&gt;
&lt;br /&gt;
[10] '''How and why session IDs are reused in ASP.NET''' https://support.microsoft.com/en-us/kb/899918&lt;br /&gt;
&lt;br /&gt;
= Authors and Primary Editors  =&lt;br /&gt;
&lt;br /&gt;
Raul Siles (DinoSec) - raul[at]dinosec.com &lt;br /&gt;
&lt;br /&gt;
== Other Cheatsheets ==&lt;br /&gt;
&lt;br /&gt;
{{Cheatsheet_Navigation_Body}}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cheatsheets]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=Session_Management_Cheat_Sheet&amp;diff=231493</id>
		<title>Session Management Cheat Sheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=Session_Management_Cheat_Sheet&amp;diff=231493"/>
				<updated>2017-07-10T09:26:25Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: Add link to PHP vote against defaulting to strict session management, to make it clear that whilst &amp;quot;strict&amp;quot; is more common in terms of systems, many many permissive systems exist.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; __NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;width:100%;height:160px;border:0,margin:0;overflow: hidden;&amp;quot;&amp;gt;[[File:Cheatsheets-header.jpg|link=]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;padding: 0;margin:0;margin-top:10px;text-align:left;&amp;quot; |-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; style=&amp;quot;border-right: 1px dotted gray;padding-right:25px;&amp;quot; |&lt;br /&gt;
Last revision (mm/dd/yy): '''{{REVISIONMONTH}}/{{REVISIONDAY}}/{{REVISIONYEAR}}''' &lt;br /&gt;
= Introduction  =&lt;br /&gt;
 __TOC__{{TOC hidden}}&lt;br /&gt;
&lt;br /&gt;
'''Web Authentication, Session Management, and Access Control''' &lt;br /&gt;
&lt;br /&gt;
A web session is a sequence of network HTTP request and response transactions associated to the same user. Modern and complex web applications require the retaining of information or status about each user for the duration of multiple requests. Therefore, sessions provide the ability to establish variables – such as access rights and localization settings – which will apply to each and every interaction a user has with the web application for the duration of the session. &lt;br /&gt;
&lt;br /&gt;
Web applications can create sessions to keep track of anonymous users after the very first user request. An example would be maintaining the user language preference. Additionally, web applications will make use of sessions once the user has authenticated. This ensures the ability to identify the user on any subsequent requests as well as being able to apply security access controls, authorized access to the user private data, and to increase the usability of the application. Therefore, current web applications can provide session capabilities both pre and post authentication. &lt;br /&gt;
&lt;br /&gt;
Once an authenticated session has been established, the session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as username and password, passphrases, one-time passwords (OTP), client-based digital certificates, smartcards, or biometrics (such as fingerprint or eye retina). See the OWASP Authentication Cheat Sheet: https://www.owasp.org/index.php/Authentication_Cheat_Sheet. &lt;br /&gt;
&lt;br /&gt;
HTTP is a stateless protocol (RFC2616 [5]), where each request and response pair is independent of other web interactions. Therefore, in order to introduce the concept of a session, it is required to implement session management capabilities that link both the authentication and access control (or authorization) modules commonly available in web applications: &lt;br /&gt;
&lt;br /&gt;
[[Image:Session-Management-Diagram Cheat-Sheet.png|center|Session-Management-Diagram Cheat-Sheet.png]] &amp;lt;br&amp;gt; The session ID or token binds the user authentication credentials (in the form of a user session) to the user HTTP traffic and the appropriate access controls enforced by the web application. The complexity of these three components (authentication, session management, and access control) in modern web applications, plus the fact that its implementation and binding resides on the web developer’s hands (as web development framework do not provide strict relationships between these modules), makes the implementation of a secure session management module very challenging. &lt;br /&gt;
&lt;br /&gt;
The disclosure, capture, prediction, brute force, or fixation of the session ID will lead to session hijacking (or sidejacking) attacks, where an attacker is able to fully impersonate a victim user in the web application. Attackers can perform two types of session hijacking attacks, targeted or generic. In a targeted attack, the attacker’s goal is to impersonate a specific (or privileged) web application victim user. For  generic attacks, the attacker’s goal is to impersonate (or get access as) any valid or legitimate user in the web application. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session ID Properties  =&lt;br /&gt;
&lt;br /&gt;
In order to keep the authenticated state and track the users progress within the web application, applications provide users with a session identifier (session ID or token) that is assigned at session creation time, and is shared and exchanged by the user and the web application for the duration of the session (it is sent on every HTTP request). The session ID is a “name=value” pair. &lt;br /&gt;
&lt;br /&gt;
With the goal of implementing secure session IDs, the generation of identifiers (IDs or tokens) must meet the following properties: &lt;br /&gt;
&lt;br /&gt;
== Session ID Name Fingerprinting  ==&lt;br /&gt;
&lt;br /&gt;
The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID. &lt;br /&gt;
&lt;br /&gt;
The session ID names used by the most common web application development frameworks can be easily fingerprinted [0], such as PHPSESSID (PHP), JSESSIONID (J2EE), CFID &amp;amp;amp; CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Therefore, the session ID name can disclose the technologies and programming languages used by the web application. &lt;br /&gt;
&lt;br /&gt;
It is recommended to change the default session ID name of the web development framework to a generic name, such as “id”. &lt;br /&gt;
&lt;br /&gt;
== Session ID Length  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be long enough to prevent brute force attacks, where an attacker can go through the whole range of ID values and verify the existence of valid sessions. &lt;br /&gt;
&lt;br /&gt;
The session ID length must be at least 128 bits (16 bytes).&lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': The session ID length of 128 bits is provided as a reference based on the assumptions made on the next section &amp;quot;Session ID Entropy&amp;quot;. However, this number should not be considered as an absolute minimum value, as other implementation factors might influence its strength. For example, there are well-known implementations, such as Microsoft ASP.NET, making use of 120-bit random numbers for its session IDs (represented by 20-character strings [10]) that can provide a very good effective entropy, and as a result, can be considered long enough to avoid guessing or brute force attacks.&lt;br /&gt;
&lt;br /&gt;
== Session ID Entropy  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict the ID of a valid session through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used. &lt;br /&gt;
&lt;br /&gt;
The session ID value must provide at least 64 bits of entropy (if a good PRNG is used, this value is estimated to be half the length of the session ID).&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': The session ID entropy is really affected by other external and difficult to measure factors, such as the number of concurrent active sessions the web application commonly has, the absolute session expiration timeout, the amount of session ID guesses per second the attacker can make and the target web application can support, etc [2]. If a session ID with an entropy of 64 bits is used, it will take an attacker at least 292 years to successfully guess a valid session ID, assuming the attacker can try 10,000 guesses per second with 100,000 valid simultaneous sessions available in the web application [2]. &lt;br /&gt;
&lt;br /&gt;
== Session ID Content (or Value)  ==&lt;br /&gt;
&lt;br /&gt;
The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application. &lt;br /&gt;
&lt;br /&gt;
The session ID must simply be an identifier on the client side, and its value must never include sensitive information (or PII). The meaning and business or application logic associated to the session ID must be stored on the server side, and specifically, in session objects or in a session management database or repository. The stored information can include the client IP address, User-Agent, e-mail, username, user ID, role, privilege level, access rights, language preferences, account ID, current state, last login, session timeouts, and other internal session details. If the session objects and properties contain sensitive information, such as credit card numbers, it is required to duly encrypt and protect the session management repository. &lt;br /&gt;
&lt;br /&gt;
It is recommended to create cryptographically strong session IDs through the usage of cryptographic hash functions such as SHA1 (160 bits). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Management Implementation  =&lt;br /&gt;
&lt;br /&gt;
The session management implementation defines the exchange mechanism that will be used between the user and the web application to share and continuously exchange the session ID. There are multiple mechanisms available in HTTP to maintain session state within web applications, such as cookies (standard HTTP header), URL parameters (URL rewriting – RFC 2396), URL arguments on GET requests, body arguments on POST requests, such as hidden form fields (HTML forms), or proprietary HTTP headers. &lt;br /&gt;
&lt;br /&gt;
The preferred session ID exchange mechanism should allow defining advanced token properties, such as the token expiration date and time, or granular usage constraints. This is one of the reasons why cookies (RFCs 2109 &amp;amp;amp; 2965 &amp;amp;amp; 6265 [1]) are one of the most extensively used session ID exchange mechanisms, offering advanced capabilities not available in other methods. &lt;br /&gt;
&lt;br /&gt;
The usage of specific session ID exchange mechanisms, such as those where the ID is included in the URL, might disclose the session ID (in web links and logs, web browser history and bookmarks, the Referer header or search engines), as well as facilitate other attacks, such as the manipulation of the ID or session fixation attacks [3]. &lt;br /&gt;
&lt;br /&gt;
== Built-in Session Management Implementations  ==&lt;br /&gt;
&lt;br /&gt;
Web development frameworks, such as J2EE, ASP .NET, PHP, and others, provide their own session management features and associated implementation. It is recommended to use these built-in frameworks versus building a home made one from scratch, as they are used worldwide on multiple web environments and have been tested by the web application security and development communities over time. &lt;br /&gt;
&lt;br /&gt;
However, be advised that these frameworks have also presented vulnerabilities and weaknesses in the past, so it is always recommended to use the latest version available, that potentially fixes all the well-known vulnerabilities, as well as review and change the default configuration to enhance its security by following the recommendations described along this document. &lt;br /&gt;
&lt;br /&gt;
The storage capabilities or repository used by the session management mechanism to temporarily save the session IDs must be secure, protecting the session IDs against local or remote accidental disclosure or unauthorized access. &lt;br /&gt;
&lt;br /&gt;
== Used vs. Accepted Session ID Exchange Mechanisms  ==&lt;br /&gt;
&lt;br /&gt;
A web application should make use of cookies for session ID exchange management. If a user submits a session ID through a different exchange mechanism, such as a URL parameter, the web application should avoid accepting it as part of a defensive strategy to stop session fixation.&lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': Even if a web application makes use of cookies as its default session ID exchange mechanism, it might accept other exchange mechanisms too. It is therefore required to confirm via thorough testing all the different mechanisms currently accepted by the web application when processing and managing session IDs, and limit the accepted session ID tracking mechanisms to just cookies. In the past, some web applications used URL parameters, or even switched from cookies to URL parameters (via automatic URL rewriting), if certain conditions are met (for example, the identification of web clients without support for cookies or not accepting cookies due to user privacy concerns).&lt;br /&gt;
&lt;br /&gt;
== Transport Layer Security  ==&lt;br /&gt;
&lt;br /&gt;
In order to protect the session ID exchange from active eavesdropping and passive disclosure in the network traffic, it is mandatory to use an encrypted HTTPS (SSL/TLS) connection for the entire web session, not only for the authentication process where the user credentials are exchanged. &lt;br /&gt;
&lt;br /&gt;
Additionally, the “Secure” cookie attribute (see below) must be used to ensure the session ID is only exchanged through an encrypted channel. The usage of an encrypted communication channel also protects the session against some session fixation attacks where the attacker is able to intercept and manipulate the web traffic to inject (or fix) the session ID on the victims web browser [4]. &lt;br /&gt;
&lt;br /&gt;
The following set of HTTPS (SSL/TLS) best practices are focused on protecting the session ID (specifically when cookies are used) and helping with the integration of HTTPS within the web application: &lt;br /&gt;
&lt;br /&gt;
*Web applications should never switch a given session from HTTP to HTTPS, or viceversa, as this will disclose the session ID in the clear through the network. &lt;br /&gt;
*Web applications should not mix encrypted and unencrypted contents (HTML pages, images, CSS, Javascript files, etc) on the same host (or even domain - see the “domain” cookie attribute), as the request of any web object over an unencrypted channel might disclose the session ID. &lt;br /&gt;
*Web applications, in general, should not offer public unencrypted contents and private encrypted contents from the same host. It is recommended to instead use two different hosts, such as www.example.com over HTTP (unencrypted) for the public contents, and secure.example.com over HTTPS (encrypted) for the private and sensitive contents (where sessions exist). The former host only has port TCP/80 open, while the later only has port TCP/443 open. &lt;br /&gt;
*Web applications should avoid the extremely common HTTP to HTTPS redirection on the home page (using a 30x HTTP response), as this single unprotected HTTP request/response exchange can be used by an attacker to gather (or fix) a valid session ID.&lt;br /&gt;
* Web applications should make use of “HTTP Strict Transport Security (HSTS)” (previously called STS) to enforce HTTPS connections.&lt;br /&gt;
&lt;br /&gt;
See the OWASP Transport Layer Protection Cheat Sheet: https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet. &lt;br /&gt;
&lt;br /&gt;
It is important to emphasize that SSL/TLS (HTTPS) does not protect against session ID prediction, brute force, client-side tampering or fixation. Yet, session ID disclosure and capture from the network traffic is one of the most prevalent attack vectors even today. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Cookies  =&lt;br /&gt;
&lt;br /&gt;
The session ID exchange mechanism based on cookies provides multiple security features in the form of cookie attributes that can be used to protect the exchange of the session ID: &lt;br /&gt;
&lt;br /&gt;
== Secure Attribute  ==&lt;br /&gt;
&lt;br /&gt;
The “Secure” cookie attribute instructs web browsers to only send the cookie through an encrypted HTTPS (SSL/TLS) connection. This session protection mechanism is mandatory to prevent the disclosure of the session ID through MitM (Man-in-the-Middle) attacks. It ensures that an attacker cannot simply capture the session ID from web browser traffic. &lt;br /&gt;
&lt;br /&gt;
Forcing the web application to only use HTTPS for its communication (even when port TCP/80, HTTP, is closed in the web application host) does not protect against session ID disclosure if the “Secure” cookie has not been set - the web browser can be deceived to disclose the session ID over an unencrypted HTTP connection. The attacker can intercept and manipulate the victim user traffic and inject an HTTP unencrypted reference to the web application that will force the web browser to submit the session ID in the clear.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/SecureFlag SecureFlag]&lt;br /&gt;
&lt;br /&gt;
== HttpOnly Attribute  ==&lt;br /&gt;
&lt;br /&gt;
The “HttpOnly” cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) an ability to access the cookies via the DOM document.cookie object. This session ID protection is mandatory to prevent session ID stealing through XSS attacks. &lt;br /&gt;
&lt;br /&gt;
See the OWASP XSS Prevention Cheat Sheet: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/HttpOnly HttpOnly]&lt;br /&gt;
&lt;br /&gt;
== SameSite Attribute ==&lt;br /&gt;
SameSite allows a server define a cookie attribute making it impossible to the browser send this cookie along with cross-site requests. The main goal is mitigate the risk of cross-origin information leakage, and provides some protection against cross-site request forgery attacks.&lt;br /&gt;
&lt;br /&gt;
See also: [https://www.owasp.org/index.php/SameSite SameSite]&lt;br /&gt;
&lt;br /&gt;
== Domain and Path Attributes  ==&lt;br /&gt;
&lt;br /&gt;
The “Domain” cookie attribute instructs web browsers to only send the cookie to the specified domain and all subdomains. If the attribute is not set, by default the cookie will only be sent to the origin server. The “Path” cookie attribute instructs web browsers to only send the cookie to the specified directory or subdirectories (or paths or resources) within the web application. If the attribute is not set, by default the cookie will only be sent for the directory (or path) of the resource requested and setting the cookie. &lt;br /&gt;
&lt;br /&gt;
It is recommended to use a narrow or restricted scope for these two attributes. In this way, the “Domain” attribute should not be set (restricting the cookie just to the origin server) and the “Path” attribute should be set as restrictive as possible to the web application path that makes use of the session ID. &lt;br /&gt;
&lt;br /&gt;
Setting the “Domain” attribute to a too permissive value, such as “example.com” allows an attacker to launch attacks on the session IDs between different hosts and web applications belonging to the same domain, known as cross-subdomain cookies. For example, vulnerabilities in www.example.com might allow an attacker to get access to the session IDs from secure.example.com. &lt;br /&gt;
&lt;br /&gt;
Additionally, it is recommended not to mix web applications of different security levels on the same domain. Vulnerabilities in one of the web applications would allow an attacker to set the session ID for a different web application on the same domain by using a permissive “Domain” attribute (such as “example.com”) which is a technique that can be used in session fixation attacks [4]. &lt;br /&gt;
&lt;br /&gt;
Although the “Path” attribute allows the isolation of session IDs between different web applications using different paths on the same host, it is highly recommended not to run different web applications (especially from different security levels or scopes) on the same host. Other methods can be used by these applications to access the session IDs, such as the “document.cookie” object. Also, any web application can set cookies for any path on that host. &lt;br /&gt;
&lt;br /&gt;
Cookies are vulnerable to DNS spoofing/hijacking/poisoning attacks, where an attacker can manipulate the DNS resolution to force the web browser to disclose the session ID for a given host or domain. &lt;br /&gt;
&lt;br /&gt;
== Expire and Max-Age Attributes  ==&lt;br /&gt;
&lt;br /&gt;
Session management mechanisms based on cookies can make use of two types of cookies, non-persistent (or session) cookies, and persistent cookies. If a cookie presents the “Max-Age” (that has preference over “Expires”) or “Expires” attributes, it will be considered a persistent cookie and will be stored on disk by the web browser based until the expiration time. Typically, session management capabilities to track users after authentication make use of non-persistent cookies. This forces the session to disappear from the client if the current web browser instance is closed. Therefore, it is highly recommended to use non-persistent cookies for session management purposes, so that the session ID does not remain on the web client cache for long periods of time, from where an attacker can obtain it. &lt;br /&gt;
&lt;br /&gt;
* Ensure that sensitive information is not comprised, by ensuring that sensitive information is not persistent / encrypting / stored on a need basis for the duration of the need&lt;br /&gt;
&lt;br /&gt;
* Ensure that unauthorized activities cannot take place via cookie manipulation&lt;br /&gt;
&lt;br /&gt;
* Ensure secure flag is set to prevent accidental transmission over “the wire” in a non-secure manner&lt;br /&gt;
&lt;br /&gt;
* Determine if all state transitions in the application code properly check for the cookies and enforce their use&lt;br /&gt;
&lt;br /&gt;
* Ensure entire cookie should be encrypted if sensitive data is persisted in the cookie&lt;br /&gt;
&lt;br /&gt;
* Define all cookies being used by the application, their name and why they are needed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Session ID Life Cycle  =&lt;br /&gt;
&lt;br /&gt;
== Session ID Generation and Verification: Permissive and Strict Session Management  ==&lt;br /&gt;
&lt;br /&gt;
There are two types of session management mechanisms for web applications, permissive and strict, related to session fixation vulnerabilities. The permissive mechanism allow the web application to initially accept any session ID value set by the user as valid, creating a new session for it, while the strict mechanism enforces that the web application will only accept session ID values that have been previously generated by the web application. &lt;br /&gt;
&lt;br /&gt;
The session tokens should be handled by the web server if possible or generated via a cryptographically secure random number generator.&lt;br /&gt;
&lt;br /&gt;
Although the most common mechanism in use today is the strict one (more secure, [https://wiki.php.net/rfc/session-use-strict-mode PHP defaults to weak]). Developers must ensure that the web application does not use a permissive mechanism under certain circumstances. Web applications should never accept a session ID they have never generated, and in case of receiving one, they should generate and offer the user a new valid session ID. Additionally, this scenario should be detected as a suspicious activity and an alert should be generated. &lt;br /&gt;
&lt;br /&gt;
== Manage Session ID as Any Other User Input  ==&lt;br /&gt;
&lt;br /&gt;
Session IDs must be considered untrusted, as any other user input processed by the web application, and they must be thoroughly validated and verified. Depending on the session management mechanism used, the session ID will be received in a GET or POST parameter, in the URL or in an HTTP header (e.g. cookies). If web applications do not validate and filter out invalid session ID values before processing them, they can potentially be used to exploit other web vulnerabilities, such as SQL injection if the session IDs are stored on a relational database, or persistent XSS if the session IDs are stored and reflected back afterwards by the web application. &lt;br /&gt;
&lt;br /&gt;
== Renew the Session ID After Any Privilege Level Change  ==&lt;br /&gt;
&lt;br /&gt;
The session ID must be renewed or regenerated by the web application after any privilege level change within the associated user session. The most common scenario where the session ID regeneration is mandatory is during the authentication process, as the privilege level of the user changes from the unauthenticated (or anonymous) state to the authenticated state. Other common scenarios must also be considered, such as password changes, permission changes or switching from a regular user role to an administrator role within the web application. For all these web application critical pages, previous session IDs have to be ignored, a new session ID must be assigned to every new request received for the critical resource, and the old or previous session ID must be destroyed. &lt;br /&gt;
&lt;br /&gt;
The most common web development frameworks provide session functions and methods to renew the session ID, such as “request.getSession(true) &amp;amp;amp; HttpSession.invalidate()” (J2EE), “Session.Abandon() &amp;amp;amp; Response.Cookies.Add(new…)“ (ASP .NET), or “session_start() &amp;amp;amp; session_regenerate_id(true)” (PHP). &lt;br /&gt;
&lt;br /&gt;
The session ID regeneration is mandatory to prevent session fixation attacks [3], where an attacker sets the session ID on the victims user web browser instead of gathering the victims session ID, as in most of the other session-based attacks, and independently of using HTTP or HTTPS. This protection mitigates the impact of other web-based vulnerabilities that can also be used to launch session fixation attacks, such as HTTP response splitting or XSS [4]. &lt;br /&gt;
&lt;br /&gt;
A complementary recommendation is to use a different session ID or token name (or set of session IDs) pre and post authentication, so that the web application can keep track of anonymous users and authenticated users without the risk of exposing or binding the user session between both states. &lt;br /&gt;
&lt;br /&gt;
== Considerations When Using Multiple Cookies  ==&lt;br /&gt;
&lt;br /&gt;
If the web application uses cookies as the session ID exchange mechanism, and multiple cookies are set for a given session, the web application must verify all cookies (and enforce relationships between them) before allowing access to the user session. &lt;br /&gt;
&lt;br /&gt;
It is very common for web applications to set a user cookie pre-authentication over HTTP to keep track of unauthenticated (or anonymous) users. Once the user authenticates in the web application, a new post-authentication secure cookie is set over HTTPS, and a binding between both cookies and the user session is established. If the web application does not verify both cookies for authenticated sessions, an attacker can make use of the pre-authentication unprotected cookie to get access to the authenticated user session [4]. &lt;br /&gt;
&lt;br /&gt;
Web applications should try to avoid the same cookie name for different paths or domain scopes within the same web application, as this increases the complexity of the solution and potentially introduces scoping issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Session Expiration  =&lt;br /&gt;
&lt;br /&gt;
In order to minimize the time period an attacker can launch attacks over active sessions and hijack them, it is mandatory to set expiration timeouts for every session, establishing the amount of time a session will remain active. Insufficient session expiration by the web application increases the exposure of other session-based attacks, as for the attacker to be able to reuse a valid session ID and hijack the associated session, it must still be active. &lt;br /&gt;
&lt;br /&gt;
The shorter the session interval is, the lesser the time an attacker has to use the valid session ID. The session expiration timeout values must be set accordingly with the purpose and nature of the web application, and balance security and usability, so that the user can comfortably complete the operations within the web application without his session frequently expiring. Both the idle and absolute timeout values are highly dependent on how critical the web application and its data are. Common idle timeouts ranges are 2-5 minutes for high-value applications and 15- 30 minutes for low risk applications. &lt;br /&gt;
&lt;br /&gt;
When a session expires, the web application must take active actions to invalidate the session on both sides, client and server. The latter is the most relevant and mandatory from a security perspective. &lt;br /&gt;
&lt;br /&gt;
For most session exchange mechanisms, client side actions to invalidate the session ID are based on clearing out the token value. For example, to invalidate a cookie it is recommended to provide an empty (or invalid) value for the session ID, and set the “Expires” (or “Max-Age”) attribute to a date from the past (in case a persistent cookie is being used): &lt;br /&gt;
&amp;lt;pre&amp;gt;Set-Cookie: id=; Expires=Friday, 17-May-03 18:45:00 GMT &amp;lt;/pre&amp;gt; &lt;br /&gt;
In order to close and invalidate the session on the server side, it is mandatory for the web application to take active actions when the session expires, or the user actively logs out, by using the functions and methods offered by the session management mechanisms, such as “HttpSession.invalidate()” (J2EE), “Session.Abandon()“ (ASP .NET) or “session_destroy()/unset()“ (PHP). &lt;br /&gt;
&lt;br /&gt;
== Automatic Session Expiration  ==&lt;br /&gt;
&lt;br /&gt;
=== Idle Timeout  ===&lt;br /&gt;
&lt;br /&gt;
All sessions should implement an idle or inactivity timeout. This timeout defines the amount of time a session will remain active in case there is no activity in the session, closing and invalidating the session upon the defined idle period since the last HTTP request received by the web application for a given session ID. &lt;br /&gt;
&lt;br /&gt;
The idle timeout limits the chances an attacker has to guess and use a valid session ID from another user. However, if the attacker is able to hijack a given session, the idle timeout does not limit the attacker’s actions, as he can generate activity on the session periodically to keep the session active for longer periods of time. &lt;br /&gt;
&lt;br /&gt;
Session timeout management and expiration must be enforced server-side. If the client is used to enforce the session timeout, for example using the session token or other client parameters to track time references (e.g. number of minutes since login time), an attacker could manipulate these to extend the session duration. &lt;br /&gt;
&lt;br /&gt;
=== Absolute Timeout  ===&lt;br /&gt;
&lt;br /&gt;
All sessions should implement an absolute timeout, regardless of session activity. This timeout defines the maximum amount of time a session can be active, closing and invalidating the session upon the defined absolute period since the given session was initially created by the web application. After invalidating the session, the user is forced to (re)authenticate again in the web application and establish a new session. &lt;br /&gt;
&lt;br /&gt;
The absolute session limits the amount of time an attacker can use a hijacked session and impersonate the victim user. &lt;br /&gt;
&lt;br /&gt;
=== Renewal Timeout  ===&lt;br /&gt;
&lt;br /&gt;
Alternatively, the web application can implement an additional renewal timeout after which the session ID is automatically renewed, in the middle of the user session, and independently of the session activity and, therefore, of the idle timeout. &lt;br /&gt;
&lt;br /&gt;
After a specific amount of time since the session was initially created, the web application can regenerate a new ID for the user session and try to set it, or renew it, on the client. The previous session ID value would still be valid for some time, accommodating a safety interval, before the client is aware of the new ID and starts using it. At that time, when the client switches to the new ID inside the current session, the application invalidates the previous ID.&lt;br /&gt;
&lt;br /&gt;
This scenario minimizes the amount of time a given session ID value, potentially obtained by an attacker, can be reused to hijack the user session, even when the victim user session is still active. The user session remains alive and open on the legitimate client, although its associated session ID value is transparently renewed periodically during the session duration, every time the renewal timeout expires. Therefore, the renewal timeout complements the idle and absolute timeouts, specially when the absolute timeout value extends significantly over time (e.g. it is an application requirement to keep the user sessions opened for long periods of time).&lt;br /&gt;
&lt;br /&gt;
Depending of the implementation, potentially there could be a race condition where the attacker with a still valid previous session ID sends a request before the victim user, right after the renewal timeout has just expired, and obtains first the value for the renewed session ID. At least in this scenario, the victim user might be aware of the attack as her session will be suddenly terminated because her associated session ID is not valid anymore.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Manual Session Expiration  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should provide mechanisms that allow security aware users to actively close their session once they have finished using the web application. &lt;br /&gt;
&lt;br /&gt;
=== Logout Button  ===&lt;br /&gt;
&lt;br /&gt;
Web applications must provide a visible an easily accessible logout (logoff, exit, or close session) button that is available on the web application header or menu and reachable from every web application resource and page, so that the user can manually close the session at any time. As described [[Session_Management_Cheat_Sheet#Session_Expiration|above]], the web application must invalidate the session at least on server side.&lt;br /&gt;
&lt;br /&gt;
'''NOTE''': Unfortunately, not all web applications facilitate users to close their current session. Thus, client-side enhancements such as the PopUp LogOut Firefox add-on [9] allow conscientious users to protect their sessions by helping to close them diligently.&lt;br /&gt;
&lt;br /&gt;
== Web Content Caching  ==&lt;br /&gt;
&lt;br /&gt;
Even after the session has been closed, it might be possible to access the private or sensitive data exchanged within the session through the web browser cache. Therefore, web applications must use restrictive cache directives for all the web traffic exchanged through HTTP and HTTPS, such as the “Cache-Control: no-cache,no-store” and “Pragma: no-cache” HTTP headers [5], and/or equivalent META tags on all or (at least) sensitive web pages. &lt;br /&gt;
&lt;br /&gt;
Independently of the cache policy defined by the web application, if caching web application contents is allowed, the session IDs must never be cached, so it is highly recommended to use the “Cache-Control: no-cache=&amp;quot;Set-Cookie, Set-Cookie2&amp;quot;” directive, to allow web clients to cache everything except the session ID. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Additional Client-Side Defenses for Session Management  =&lt;br /&gt;
&lt;br /&gt;
Web applications can complement the previously described session management defenses with additional countermeasures on the client side. Client-side protections, typically in the form of JavaScript checks and verifications, are not bullet proof and can easily be defeated by a skilled attacker, but can introduce another layer of defense that has to be bypassed by intruders. &lt;br /&gt;
&lt;br /&gt;
== Initial Login Timeout  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code in the login page to evaluate and measure the amount of time since the page was loaded and a session ID was granted. If a login attempt is tried after a specific amount of time, the client code can notify the user that the maximum amount of time to log in has passed and reload the login page, hence retrieving a new session ID. &lt;br /&gt;
&lt;br /&gt;
This extra protection mechanism tries to force the renewal of the session ID pre-authentication, avoiding scenarios where a previously used (or manually set) session ID is reused by the next victim using the same computer, for example, in session fixation attacks. &lt;br /&gt;
&lt;br /&gt;
== Force Session Logout On Web Browser Window Close Events  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code to capture all the web browser tab or window close (or even back) events and take the appropriate actions to close the current session before closing the web browser, emulating that the user has manually closed the session via the logout button. &lt;br /&gt;
&lt;br /&gt;
== Disable Web Browser Cross-Tab Sessions  ==&lt;br /&gt;
&lt;br /&gt;
Web applications can use JavaScript code once the user has logged in and a session has been established to force the user to re-authenticate if a new web browser tab or window is opened against the same web application. The web application does not want to allow multiple web browser tabs or windows to share the same session. Therefore, the application tries to force the web browser to not share the same session ID simultaneously between them. &lt;br /&gt;
&lt;br /&gt;
'''''NOTE''''': This mechanism cannot be implemented if the session ID is exchanged through cookies, as cookies are shared by all web browser tabs/windows.&amp;amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
== Automatic Client Logout ==&lt;br /&gt;
&lt;br /&gt;
JavaScript code can be used by the web application in all (or critical) pages to automatically logout client sessions after the idle timeout expires, for example, by redirecting the user to the logout page (the same resource used by the logout button mentioned previously). &lt;br /&gt;
&lt;br /&gt;
The benefit of enhancing the server-side idle timeout functionality with client-side code is that the user can see that the session has finished due to inactivity, or even can be notified in advance that the session is about to expire through a count down timer and warning messages. This user-friendly approach helps to avoid loss of work in web pages that require extensive input data due to server-side silently expired sessions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Attacks Detection  =&lt;br /&gt;
&lt;br /&gt;
== Session ID Guessing and Brute Force Detection  ==&lt;br /&gt;
&lt;br /&gt;
If an attacker tries to guess or brute force a valid session ID, he needs to launch multiple sequential requests against the target web application using different session IDs from a single (or set of) IP address(es). Additionally, if an attacker tries to analyze the predictability of the session ID (e.g. using statistical analysis), he needs to launch multiple sequential requests from a single (or set of) IP address(es) against the target web application to gather new valid session IDs. &lt;br /&gt;
&lt;br /&gt;
Web applications must be able to detect both scenarios based on the number of attempts to gather (or use) different session IDs and alert and/or block the offending IP address(es). &lt;br /&gt;
&lt;br /&gt;
== Detecting Session ID Anomalies  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should focus on detecting anomalies associated to the session ID, such as its manipulation. The OWASP AppSensor Project [7] provides a framework and methodology to implement built-in intrusion detection capabilities within web applications focused on the detection of anomalies and unexpected behaviors, in the form of detection points and response actions. Instead of using external protection layers, sometimes the business logic details and advanced intelligence are only available from inside the web application, where it is possible to establish multiple session related detection points, such as when an existing cookie is modified or deleted, a new cookie is added, the session ID from another user is reused, or when the user location or User-Agent changes in the middle of a session. &lt;br /&gt;
&lt;br /&gt;
== Binding the Session ID to Other User Properties  ==&lt;br /&gt;
&lt;br /&gt;
With the goal of detecting (and, in some scenarios, protecting against) user misbehaviors and session hijacking, it is highly recommended to bind the session ID to other user or client properties, such as the client IP address, User-Agent, or client-based digital certificate. If the web application detects any change or anomaly between these different properties in the middle of an established session, this is a very good indicator of session manipulation and hijacking attempts, and this simple fact can be used to alert and/or terminate the suspicious session. &lt;br /&gt;
&lt;br /&gt;
Although these properties cannot be used by web applications to trustingly defend against session attacks, they significantly increase the web application detection (and protection) capabilities. However, a skilled attacker can bypass these controls by reusing the same IP address assigned to the victim user by sharing the same network (very common in NAT environments, like Wi-Fi hotspots) or by using the same outbound web proxy (very common in corporate environments), or by manually modifying his User-Agent to look exactly as the victim users does. &lt;br /&gt;
&lt;br /&gt;
== Logging Sessions Life Cycle: Monitoring Creation, Usage, and Destruction of Session IDs  ==&lt;br /&gt;
&lt;br /&gt;
Web applications should increase their logging capabilities by including information regarding the full life cycle of sessions. In particular, it is recommended to record session related events, such as the creation, renewal, and destruction of session IDs, as well as details about its usage within login and logout operations, privilege level changes within the session, timeout expiration, invalid session activities (when detected), and critical business operations during the session. &lt;br /&gt;
&lt;br /&gt;
The log details might include a timestamp, source IP address, web target resource requested (and involved in a session operation), HTTP headers (including the User-Agent and Referer), GET and POST parameters, error codes and messages, username (or user ID), plus the session ID (cookies, URL, GET, POST…). Sensitive data like the session ID should not be included in the logs in order to protect the session logs against session ID local or remote disclosure or unauthorized access. However, some kind of session-specific information must be logged into order to correlate log entries to specific sessions. It is recommended to log a salted-hash of the session ID instead of the session ID itself in order to allow for session-specific log correlation without exposing the session ID.&lt;br /&gt;
&lt;br /&gt;
In particular, web applications must thoroughly protect administrative interfaces that allow to manage all the current active sessions. Frequently these are used by support personnel to solve session related issues, or even general issues, by impersonating the user and looking at the web application as the user does.&lt;br /&gt;
&lt;br /&gt;
The session logs become one of the main web application intrusion detection data sources, and can also be used by intrusion protection systems to automatically terminate sessions and/or disable user accounts when (one or many) attacks are detected. If active protections are implemented, these defensive actions must be logged too.&lt;br /&gt;
&lt;br /&gt;
== Simultaneous Session Logons  ==&lt;br /&gt;
&lt;br /&gt;
It is the web application design decision to determine if multiple simultaneous logons from the same user are allowed from the same or from different client IP addresses. If the web application does not want to allow simultaneous session logons, it must take effective actions after each new authentication event, implicitly terminating the previously available session, or asking the user (through the old, new or both sessions) about the session that must remain active. &lt;br /&gt;
&lt;br /&gt;
It is recommended for web applications to add user capabilities that allow checking the details of active sessions at any time, monitor and alert the user about concurrent logons, provide user features to remotely terminate sessions manually, and track account activity history (logbook) by recording multiple client details such as IP address, User-Agent, login date and time, idle time, etc. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Session Management WAF Protections  =&lt;br /&gt;
&lt;br /&gt;
There are situations where the web application source code is not available or cannot be modified, or when the changes required to implement the multiple security recommendations and best practices detailed above imply a full redesign of the web application architecture, and therefore, cannot be easily implemented in the short term. In these scenarios, or to complement the web application defenses, and with the goal of keeping the web application as secure as possible, it is recommended to use external protections such as Web Application Firewalls (WAFs) that can mitigate the session management threats already described. &lt;br /&gt;
&lt;br /&gt;
Web Application Firewalls offer detection and protection capabilities against session based attacks. On the one hand, it is trivial for WAFs to enforce the usage of security attributes on cookies, such as the “Secure” and “HttpOnly” flags, applying basic rewriting rules on the “Set-Cookie” header for all the web application responses that set a new cookie. On the other hand, more advanced capabilities can be implemented to allow the WAF to keep track of sessions, and the corresponding session IDs, and apply all kind of protections against session fixation (by renewing the session ID on the client-side when privilege changes are detected), enforcing sticky sessions (by verifying the relationship between the session ID and other client properties, like the IP address or User-Agent), or managing session expiration (by forcing both the client and the web application to finalize the session). &lt;br /&gt;
&lt;br /&gt;
The open-source ModSecurity WAF, plus the OWASP Core Rule Set [6], provide capabilities to detect and apply security cookie attributes, countermeasures against session fixation attacks, and session tracking features to enforce sticky sessions. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
= Related Articles  =&lt;br /&gt;
&lt;br /&gt;
[0] '''OWASP Cookies Database. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_Cookies_Database &lt;br /&gt;
&lt;br /&gt;
[1] '''&amp;quot;HTTP State Management Mechanism&amp;quot;. RFC 6265. IETF.''' http://tools.ietf.org/html/rfc6265 &lt;br /&gt;
&lt;br /&gt;
[2] '''Insufficient Session-ID Length. OWASP.''' https://www.owasp.org/index.php/Insufficient_Session-ID_Length &lt;br /&gt;
&lt;br /&gt;
[3] '''Session Fixation. Mitja Kolšek. 2002.''' http://www.acrossecurity.com/papers/session_fixation.pdf &lt;br /&gt;
&lt;br /&gt;
[4] '''&amp;quot;SAP: Session (Fixation) Attacks and Protections (in Web Applications)&amp;quot;. Raul Siles. BlackHat EU 2011.''' &lt;br /&gt;
&lt;br /&gt;
https://media.blackhat.com/bh-eu-11/Raul_Siles/BlackHat_EU_2011_Siles_SAP_Session-Slides.pdf &lt;br /&gt;
&lt;br /&gt;
https://media.blackhat.com/bh-eu-11/Raul_Siles/BlackHat_EU_2011_Siles_SAP_Session-WP.pdf &lt;br /&gt;
&lt;br /&gt;
[5] '''&amp;quot;Hypertext Transfer Protocol -- HTTP/1.1&amp;quot;. RFC2616. IETF.''' http://tools.ietf.org/html/rfc2616 &lt;br /&gt;
&lt;br /&gt;
[6] '''OWASP ModSecurity Core Rule Set (CSR) Project. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project &lt;br /&gt;
&lt;br /&gt;
[7] '''OWASP AppSensor Project. OWASP.''' https://www.owasp.org/index.php/Category:OWASP_AppSensor_Project &lt;br /&gt;
&lt;br /&gt;
[8] '''HttpOnly Session ID in URL and Page Body | Cross Site Scripting''' http://seckb.yehg.net/2012/06/httponly-session-id-in-url-and-page.html&lt;br /&gt;
&lt;br /&gt;
[9] '''PopUp LogOut Firefox add-on''' https://addons.mozilla.org/en-US/firefox/addon/popup-logout/ &amp;amp; http://popuplogout.iniqua.com&lt;br /&gt;
&lt;br /&gt;
[10] '''How and why session IDs are reused in ASP.NET''' https://support.microsoft.com/en-us/kb/899918&lt;br /&gt;
&lt;br /&gt;
= Authors and Primary Editors  =&lt;br /&gt;
&lt;br /&gt;
Raul Siles (DinoSec) - raul[at]dinosec.com &lt;br /&gt;
&lt;br /&gt;
== Other Cheatsheets ==&lt;br /&gt;
&lt;br /&gt;
{{Cheatsheet_Navigation_Body}}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cheatsheets]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=200170</id>
		<title>HTTP Strict Transport Security</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=200170"/>
				<updated>2015-09-07T16:14:02Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: /* Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
HTTP Strict Transport Security (HSTS) is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers.&lt;br /&gt;
&lt;br /&gt;
The specification has been released and published end of 2012 as RFC 6797 (HTTP Strict Transport Security (HSTS)) by the IETF. (Reference see in the links at the bottom.)&lt;br /&gt;
&lt;br /&gt;
== Threats ==&lt;br /&gt;
&lt;br /&gt;
HSTS addresses the following threats:&lt;br /&gt;
* User bookmarks or manually types http://example.com and is subject to a man-in-the-middle attacker&lt;br /&gt;
** HSTS automatically redirects HTTP requests to HTTPS for the target domain&lt;br /&gt;
* Web application that is intended to be purely HTTPS inadvertently contains HTTP links or serves content over HTTP&lt;br /&gt;
** HSTS automatically redirects HTTP requests to HTTPS for the target domain&lt;br /&gt;
* A man-in-the-middle attacker attempts to intercept traffic from a victim user using an invalid certificate and hopes the user will accept the bad certificate&lt;br /&gt;
** HSTS does not allow a user to override the invalid certificate message&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
Simple example, using a long (1 year) max-age:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000&lt;br /&gt;
&lt;br /&gt;
If all present and future subdomains will be HTTPS:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000; includeSubDomains&lt;br /&gt;
&lt;br /&gt;
'''Recommended:''' If the site owner would like their domain to be included in the [https://hstspreload.appspot.com/ HSTS preload list] maintained by Chrome (and used by Firefox and Safari), then use:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload&lt;br /&gt;
&lt;br /&gt;
The `preload` flag indicates the site owner's consent to have their domain preloaded. The site owner still needs to then go and submit the domain to the list.&lt;br /&gt;
&lt;br /&gt;
== Problems ==&lt;br /&gt;
&lt;br /&gt;
Site owners can use HSTS to identify users without cookies. This can lead to a significant privacy leak[http://www.leviathansecurity.com/blog/the-double-edged-sword-of-hsts-persistence-and-privacy].&lt;br /&gt;
&lt;br /&gt;
Cookies can be manipulated from sub-domains, so omitting the include &amp;quot;includeSubDomains&amp;quot; option permits a broad range of cookie-related attacks that HSTS would otherwise prevent by requiring a valid certificate for a subdomain. Ensuring the &amp;quot;Secure Flag&amp;quot; is set on all cookies will also prevent, some, but not all, of the same attacks.&lt;br /&gt;
&lt;br /&gt;
== Browser Support ==&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;400&amp;quot; cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;1&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Browser'''&amp;lt;br&amp;gt;&lt;br /&gt;
| '''Support Introduced'''&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Internet Explorer &amp;lt;br&amp;gt;&lt;br /&gt;
| Internet Explorer 11 on Windows 8.1 and Windows 7[http://blogs.windows.com/msedgedev/2015/06/09/http-strict-transport-security-comes-to-internet-explorer-11-on-windows-8-1-and-windows-7/]&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Firefox&amp;lt;br&amp;gt;&lt;br /&gt;
| 4&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Opera&amp;lt;br&amp;gt;&lt;br /&gt;
| 12&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Safari&amp;lt;br&amp;gt;&lt;br /&gt;
| Mavericks (Mac OS X 10.9)&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Chrome&amp;lt;br&amp;gt;&lt;br /&gt;
| 4.0.211.0&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A detailed overview of supporting browsers can be found at [http://caniuse.com/#feat=stricttransportsecurity caniuse.com]. There is also a [https://badssl.com/ TLS Browser Test Page] to check whether your current browser supports HSTS.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [http://www.youtube.com/watch?v=zEV3HOuM_Vw&amp;amp;feature=youtube_gdata AppSecTutorial Series - Episode 4]&lt;br /&gt;
* [http://dev.chromium.org/sts Chromium Projects/HSTS]&lt;br /&gt;
* [http://tools.ietf.org/html/rfc6797 HSTS Spec]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security Wikipedia]&lt;br /&gt;
* [https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Mozilla Developer Network]&lt;br /&gt;
* [https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet OWASP TLS Protection Cheat Sheet]&lt;br /&gt;
* [https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Firefox STS Support]&lt;br /&gt;
* [http://lists.w3.org/Archives/Public/public-webapps/2009JulSep/1148.html Google Chrome STS Support]&lt;br /&gt;
* [http://www.thoughtcrime.org/software/sslstrip/ Moxie Marlinspike's Black Hat 2009 talk on sslstrip, that demonstrates why you need HSTS]&lt;br /&gt;
&lt;br /&gt;
[[Category:Control|Control]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=200169</id>
		<title>HTTP Strict Transport Security</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=200169"/>
				<updated>2015-09-07T16:12:42Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: /* Problems */ Added reference that the non-overlap of HSTS and Cookie scope re-enables a number of cookie attacks which would otherwise be presented.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
HTTP Strict Transport Security (HSTS) is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers.&lt;br /&gt;
&lt;br /&gt;
The specification has been released and published end of 2012 as RFC 6797 (HTTP Strict Transport Security (HSTS)) by the IETF. (Reference see in the links at the bottom.)&lt;br /&gt;
&lt;br /&gt;
== Threats ==&lt;br /&gt;
&lt;br /&gt;
HSTS addresses the following threats:&lt;br /&gt;
* User bookmarks or manually types http://example.com and is subject to a man-in-the-middle attacker&lt;br /&gt;
** HSTS automatically redirects HTTP requests to HTTPS for the target domain&lt;br /&gt;
* Web application that is intended to be purely HTTPS inadvertently contains HTTP links or serves content over HTTP&lt;br /&gt;
** HSTS automatically redirects HTTP requests to HTTPS for the target domain&lt;br /&gt;
* A man-in-the-middle attacker attempts to intercept traffic from a victim user using an invalid certificate and hopes the user will accept the bad certificate&lt;br /&gt;
** HSTS does not allow a user to override the invalid certificate message&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
Simple example, using a long (1 year) max-age:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000&lt;br /&gt;
&lt;br /&gt;
If all present and future subdomains will be HTTPS:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000; includeSubDomains&lt;br /&gt;
&lt;br /&gt;
'''Recommended:''' If the site owner would like their domain to be included in the [https://hstspreload.appspot.com/ HSTS preload list] maintained by Chrome (and used by Firefox and Safari), then use:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload&lt;br /&gt;
&lt;br /&gt;
The `preload` flag indicates the site owner's consent to have their domain preloaded. The site owner still needs to then go and submit the domain to the list.&lt;br /&gt;
&lt;br /&gt;
== Problems ==&lt;br /&gt;
&lt;br /&gt;
Site owners can use HSTS to identify users without cookies. This can lead to a significant privacy leak[http://www.leviathansecurity.com/blog/the-double-edged-sword-of-hsts-persistence-and-privacy].&lt;br /&gt;
&lt;br /&gt;
Cookies can be manipulated from sub-domains, so omitting the include &amp;quot;includeSubDomains&amp;quot; option permits a broad range of cookie-related attacks that HSTS would otherwise prevents by requiring a valid certificate for a subdomain. Ensuring the &amp;quot;Secure Flag&amp;quot; is set on all cookies will also prevent, some, but not all, of the same attacks.&lt;br /&gt;
&lt;br /&gt;
== Browser Support ==&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;400&amp;quot; cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;1&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Browser'''&amp;lt;br&amp;gt;&lt;br /&gt;
| '''Support Introduced'''&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Internet Explorer &amp;lt;br&amp;gt;&lt;br /&gt;
| Internet Explorer 11 on Windows 8.1 and Windows 7[http://blogs.windows.com/msedgedev/2015/06/09/http-strict-transport-security-comes-to-internet-explorer-11-on-windows-8-1-and-windows-7/]&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Firefox&amp;lt;br&amp;gt;&lt;br /&gt;
| 4&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Opera&amp;lt;br&amp;gt;&lt;br /&gt;
| 12&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Safari&amp;lt;br&amp;gt;&lt;br /&gt;
| Mavericks (Mac OS X 10.9)&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Chrome&amp;lt;br&amp;gt;&lt;br /&gt;
| 4.0.211.0&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A detailed overview of supporting browsers can be found at [http://caniuse.com/#feat=stricttransportsecurity caniuse.com]. There is also a [https://badssl.com/ TLS Browser Test Page] to check whether your current browser supports HSTS.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [http://www.youtube.com/watch?v=zEV3HOuM_Vw&amp;amp;feature=youtube_gdata AppSecTutorial Series - Episode 4]&lt;br /&gt;
* [http://dev.chromium.org/sts Chromium Projects/HSTS]&lt;br /&gt;
* [http://tools.ietf.org/html/rfc6797 HSTS Spec]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security Wikipedia]&lt;br /&gt;
* [https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Mozilla Developer Network]&lt;br /&gt;
* [https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet OWASP TLS Protection Cheat Sheet]&lt;br /&gt;
* [https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Firefox STS Support]&lt;br /&gt;
* [http://lists.w3.org/Archives/Public/public-webapps/2009JulSep/1148.html Google Chrome STS Support]&lt;br /&gt;
* [http://www.thoughtcrime.org/software/sslstrip/ Moxie Marlinspike's Black Hat 2009 talk on sslstrip, that demonstrates why you need HSTS]&lt;br /&gt;
&lt;br /&gt;
[[Category:Control|Control]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=166977</id>
		<title>HTTP Strict Transport Security</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=HTTP_Strict_Transport_Security&amp;diff=166977"/>
				<updated>2014-01-30T15:33:03Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: HSTS enabled in Mavericks, it is free upgrade so do it.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
HTTP Strict Transport Security (HSTS) is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The specification has been released and published end of 2012 as RFC 6797 (HTTP Strict Transport Security (HSTS)) by the IETF. (Reference see in the links at the bottom.)&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
Example of the HTTP strict transport security header &lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=60000&lt;br /&gt;
&lt;br /&gt;
If all subdomains are HTTPS too then the following header is applicable:&lt;br /&gt;
&lt;br /&gt;
  Strict-Transport-Security: max-age=60000; includeSubDomains&lt;br /&gt;
&lt;br /&gt;
== Browser Support ==&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;400&amp;quot; cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;1&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Browser'''&amp;lt;br&amp;gt;&lt;br /&gt;
| '''Support Introduced'''&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Internet Explorer &amp;lt;br&amp;gt;&lt;br /&gt;
| no support as of IE 10 (tested on 2013-01-01)&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Firefox&amp;lt;br&amp;gt;&lt;br /&gt;
| 4&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Opera&amp;lt;br&amp;gt;&lt;br /&gt;
| 12&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Safari&amp;lt;br&amp;gt;&lt;br /&gt;
| Mavericks (Mac OS X 10.9)&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Chrome&amp;lt;br&amp;gt;&lt;br /&gt;
| 4.0.211.0&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server Side ==&lt;br /&gt;
&lt;br /&gt;
The web server side needs to inject the HSTS header. &lt;br /&gt;
&lt;br /&gt;
For HTTP sites on the same domain it is [http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec#section-6.1 not recommended] to add a HSTS header but to do a permanent redirect (301 status code) to the HTTPS site.&lt;br /&gt;
 &lt;br /&gt;
An Apache HTTPd example that will permanently redirect a URL to the identical URL with a HTTPS scheme, is as follows:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
        ServerAlias *&lt;br /&gt;
        RewriteEngine On&lt;br /&gt;
        RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the HTTPS site configuration the following is needed to add the header as [http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec#section-6.1 recommended by the standard]:&lt;br /&gt;
        Header set Strict-Transport-Security &amp;quot;max-age=16070400; includeSubDomains&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following links show how to set response headers in other web servers:&lt;br /&gt;
* [http://wiki.nginx.org/HttpHeadersModule NGINX]&lt;br /&gt;
* [http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModSetEnv#Options Lighttpd]&lt;br /&gt;
* [http://httpd.apache.org/docs/2.2/mod/mod_headers.html HTTPd]&lt;br /&gt;
&lt;br /&gt;
==== IIS ====&lt;br /&gt;
Whilst [http://technet.microsoft.com/en-us/library/cc753133(WS.10).aspx custom headers] can be configured in IIS without any extensions, it is not possible to restrict these headers to secure transport channels [http://tools.ietf.org/html/rfc6797#section-7.2 as per the HSTS specification]. HSTS has been implemented as per the specification as an [http://hstsiis.codeplex.com/ open source IIS module].&lt;br /&gt;
&lt;br /&gt;
== Threats ==&lt;br /&gt;
&lt;br /&gt;
HSTS addresses the following threats:&lt;br /&gt;
* User bookmarks or manually types http://example.com and is subject to a man-in-the-middle attacker&lt;br /&gt;
** HSTS automatically upgrades HTTP requests to HTTPS for the target domain&lt;br /&gt;
* Web application that is intended to be purely HTTPS inadvertently contains HTTP links or serves content over HTTP&lt;br /&gt;
** HSTS automatically upgrades HTTP requests to HTTPS for the target domain&lt;br /&gt;
* A man-in-the-middle attacker attempts to intercept traffic from a victim user using an invalid certificate and hopes the user will accept the bad certificate&lt;br /&gt;
** HSTS does not allow a user to override the invalid certificate message&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
[http://dev.chromium.org/sts Chromium Projects/HSTS]&lt;br /&gt;
&lt;br /&gt;
[http://tools.ietf.org/html/rfc6797 HSTS Spec]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Mozilla Developer Network]&lt;br /&gt;
&lt;br /&gt;
[https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet OWASP TLS Protection Cheat Sheet]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security Firefox STS Support]&lt;br /&gt;
&lt;br /&gt;
[http://lists.w3.org/Archives/Public/public-webapps/2009JulSep/1148.html Google Chrome STS Support]&lt;br /&gt;
&lt;br /&gt;
[http://www.thoughtcrime.org/software/sslstrip/ Moxie Marlinspike's Black Hat 2009 talk on sslstrip, that demonstrates why you need HSTS]&lt;br /&gt;
&lt;br /&gt;
[[Category:Control|Control]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PHP_Security_Cheat_Sheet&amp;diff=149462</id>
		<title>PHP Security Cheat Sheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PHP_Security_Cheat_Sheet&amp;diff=149462"/>
				<updated>2013-04-09T00:32:26Z</updated>
		
		<summary type="html">&lt;p&gt;Simon Waters: Changes to grammar, link to doctrine, explanation of acronym ORM&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DRAFT CHEAT SHEET - WORK IN PROGRESS =&lt;br /&gt;
= Introduction  =&lt;br /&gt;
This page intends to provide basic PHP security tips for developers and administrators. Keep in mind that tips mentioned in this page may not be sufficient for securing your web application.&lt;br /&gt;
&lt;br /&gt;
==PHP status on the web==&lt;br /&gt;
PHP is the most commonly used server-side programming language and 72% of web servers deploy PHP. PHP is open source. The core of PHP is reasonably secure, but its plugins, libraries and third party tools are often insecure. Also no default security mechanism is included in PHP (there were some in the old days, but they usually broke things). &lt;br /&gt;
&lt;br /&gt;
PHP developers are usually better informed than ASPX or JSP developers on how the web and HTTP works, and that makes for better coding practices, but they both lack basic security knowledge. Other languages have built-in security mechanisms, which is why PHP websites often have more flawed. &lt;br /&gt;
&lt;br /&gt;
==Update PHP Now==&lt;br /&gt;
'''Important Note: ''' PHP 5.2.x is officially unsupported now. This means that in the near future, when a common security flaw on PHP 5.2.x is discovered, PHP 5.2.x powered website may become vulnerable. ''It is of utmost important that you upgrade your PHP to 5.3.x or 5.4.x right now.''&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that you should regularly upgrade your PHP distribution on an operational server. Every day new flaws are discovered and announced in PHP and attackers use these new flaws on random servers frequently.&lt;br /&gt;
&lt;br /&gt;
=Untrusted data=&lt;br /&gt;
All data that is a product, or subproduct, of user input is to NOT be trusted. They have to either be validated, using the correct methodology, or filtered, before considering them untainted.&lt;br /&gt;
&lt;br /&gt;
Super globals which are not to be trusted are $_SERVER, $_GET, $_POST, $_REQUEST, $_FILES and $_COOKIE. Not all data in $_SERVER can be faked by the user, but a considerable amount in it can, particularly and specially everything that deals with HTTP headers (they start with HTTP_).&lt;br /&gt;
&lt;br /&gt;
==Common mistakes on the processing of $_FILES array==&lt;br /&gt;
It is common to find code snippets online doing something similar to the following code:&lt;br /&gt;
&lt;br /&gt;
    if ($_FILES['some_name']['type'] == 'image/jpeg') {  &lt;br /&gt;
        //Proceed to accept the file as a valid image&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
However, the type is not determined by using heuristics that validate it, but by simply reading the data sent by the HTTP request, which is created by a client. A better, yet not perfect, way of validating file types is to use finfo class.&lt;br /&gt;
&lt;br /&gt;
    $finfo = new finfo(FILEINFO_MIME_TYPE);&lt;br /&gt;
    $fileContents = file_get_contents($_FILES['some_name']['tmp_name']);&lt;br /&gt;
    $mimeType = $finfo-&amp;gt;buffer($fileContents);&lt;br /&gt;
&lt;br /&gt;
Where $mimeType is a better checked file type. This uses more resources on the server, but can prevent the user from sending a dangerous file and fooling the code into trusting it as an image, which would normally be regarded as a safe file type.&lt;br /&gt;
&lt;br /&gt;
==Use of $_REQUEST==&lt;br /&gt;
Using $_REQUEST is strongly discouraged. This super global is not recommended since it includes not only POST and GET data, but also the cookies sent by the request. This can lead to confusion and makes your code prone to mistakes, which could lead to security problems.&lt;br /&gt;
&lt;br /&gt;
=Database Cheat Sheet=&lt;br /&gt;
Since a single SQL Injection vulnerability permits the hacking of your website, and every hacker first tries SQL injection flaws, fixing SQL injections are the first step to securing your PHP powered application. Abide to the following rules:&lt;br /&gt;
&lt;br /&gt;
==Encoding Issues==&lt;br /&gt;
===Everything is a string for a database===&lt;br /&gt;
There are ways to send different data types to a database, ints, floats, etc. Never rely on them, instead always send an string to the database. Database engines type cast automatically if they need to. This makes for much safer queries. Make this a habit of yours, and see how many time it saves you. Still, do not concatenate without escaping the values. Check the [[#Use Prepared Statements|Use Prepared Statements]].&lt;br /&gt;
&lt;br /&gt;
====Wrong====&lt;br /&gt;
 $x=1; &lt;br /&gt;
 SELECT * FROM users WHERE ID &amp;gt; $x&lt;br /&gt;
====Right====&lt;br /&gt;
 $x=1; // or $x='1';&lt;br /&gt;
 SELECT * FROM users WHERE ID &amp;gt;'$x';&lt;br /&gt;
&lt;br /&gt;
===Use UTF-8 unless necessary===&lt;br /&gt;
Many new attack vectors rely on encoding bypassing. Use UTF-8 as your database and application charset unless you have a mandatory requirement to use another encoding.&lt;br /&gt;
&lt;br /&gt;
    $DB = new mysqli($Host, $Username, $Password, $DatabaseName);&lt;br /&gt;
    if (mysqli_connect_errno())&lt;br /&gt;
        trigger_error(&amp;quot;Unable to connect to MySQLi database.&amp;quot;);&lt;br /&gt;
    $DB-&amp;gt;set_charset('UTF-8');&lt;br /&gt;
&lt;br /&gt;
==Escaping is not safe== &lt;br /&gt;
'''mysql_real_escape_string''' is not safe. Don't rely on it for your SQL injection prevention.&lt;br /&gt;
&lt;br /&gt;
'''Why:'''&lt;br /&gt;
When you use mysql_real_escape_string on every variable and then concat it to your query, ''you are bound to forget that at least once'', and once is all it takes. You can't force yourself in any way to never forget. Number fields might also be vulnerable if not used as strings. Instead use prepared statements or equivalent.&lt;br /&gt;
&lt;br /&gt;
==Use Prepared Statements==&lt;br /&gt;
Prepared statements are very secure. In a prepared statement, data is separated from the SQL command, so that everything user inputs is considered data and put into the table the way it was. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====MySQLi Prepared Statements Wrapper====&lt;br /&gt;
The following function, performs a SQL query, returns its results as a 2D array (if query was SELECT) and does all that with prepared statements using MySQLi fast MySQL interface:&lt;br /&gt;
&lt;br /&gt;
    $DB = new mysqli($Host, $Username, $Password, $DatabaseName);&lt;br /&gt;
    if (mysqli_connect_errno())&lt;br /&gt;
        trigger_error(&amp;quot;Unable to connect to MySQLi database.&amp;quot;);&lt;br /&gt;
    $DB-&amp;gt;set_charset('UTF-8');&lt;br /&gt;
&lt;br /&gt;
    function SQL($Query) {&lt;br /&gt;
        global $DB;&lt;br /&gt;
        $args = func_get_args();&lt;br /&gt;
        if (count($args) == 1) {&lt;br /&gt;
            $result = $DB-&amp;gt;query($Query);&lt;br /&gt;
            if ($result-&amp;gt;num_rows) {&lt;br /&gt;
                $out = array();&lt;br /&gt;
                while (null != ($r = $result-&amp;gt;fetch_array(MYSQLI_ASSOC)))&lt;br /&gt;
                    $out [] = $r;&lt;br /&gt;
                return $out;&lt;br /&gt;
            }&lt;br /&gt;
            return null;&lt;br /&gt;
        } else {&lt;br /&gt;
            if (!$stmt = $DB-&amp;gt;prepare($Query))&lt;br /&gt;
                trigger_error(&amp;quot;Unable to prepare statement: {$Query}, reason: &amp;quot; . $DB-&amp;gt;error . &amp;quot;&amp;quot;);&lt;br /&gt;
            array_shift($args); //remove $Query from args&lt;br /&gt;
            //the following three lines are the only way to copy an array values in PHP&lt;br /&gt;
            $a = array();&lt;br /&gt;
            foreach ($args as $k =&amp;gt; &amp;amp;$v)&lt;br /&gt;
                $a[$k] = &amp;amp;$v;&lt;br /&gt;
            $types = str_repeat(&amp;quot;s&amp;quot;, count($args)); //all params are strings, works well on MySQL and SQLite&lt;br /&gt;
            array_unshift($a, $types);&lt;br /&gt;
            call_user_func_array(array($stmt, 'bind_param'), $a);&lt;br /&gt;
            $stmt-&amp;gt;execute();&lt;br /&gt;
            //fetching all results in a 2D array&lt;br /&gt;
            $metadata = $stmt-&amp;gt;result_metadata();&lt;br /&gt;
            $out = array();&lt;br /&gt;
            $fields = array();&lt;br /&gt;
            if (!$metadata)&lt;br /&gt;
                return null;&lt;br /&gt;
            $length = 0;&lt;br /&gt;
            while (null != ($field = mysqli_fetch_field($metadata))) {&lt;br /&gt;
                $fields [] = &amp;amp;$out [$field-&amp;gt;name];&lt;br /&gt;
                $length+=$field-&amp;gt;length;&lt;br /&gt;
            }&lt;br /&gt;
            call_user_func_array(array(&lt;br /&gt;
                $stmt, &amp;quot;bind_result&amp;quot;&lt;br /&gt;
                    ), $fields);&lt;br /&gt;
            $output = array();&lt;br /&gt;
            $count = 0;&lt;br /&gt;
            while ($stmt-&amp;gt;fetch()) {&lt;br /&gt;
                foreach ($out as $k =&amp;gt; $v)&lt;br /&gt;
                    $output [$count] [$k] = $v;&lt;br /&gt;
                $count++;&lt;br /&gt;
            }&lt;br /&gt;
            $stmt-&amp;gt;free_result();&lt;br /&gt;
            return ($count == 0) ? null : $output;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Now you could do your every query like the example below:&lt;br /&gt;
&lt;br /&gt;
 $res=SQL(&amp;quot;SELECT * FROM users WHERE ID&amp;gt;? ORDER BY ? ASC LIMIT ?&amp;quot; , 5 , &amp;quot;Username&amp;quot; , 2);&lt;br /&gt;
&lt;br /&gt;
Every instance of ? is bound with an argument of the list, not ''replaced'' with it. MySQL 5.5+ supports ? as ORDER BY and LIMIT clause specifiers. If you're using a database that doesn't support them, see next section.&lt;br /&gt;
&lt;br /&gt;
'''REMEMBER:''' When you use this approach, you should ''NEVER'' concat strings for a SQL query.&lt;br /&gt;
&lt;br /&gt;
====PDO Prepared Statement Wrapper====&lt;br /&gt;
The following function, does the same thing as the above function but using PDO. You can use it with every PDO supported driver.&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        $DB = new PDO(&amp;quot;{$Driver}:dbname={$DatabaseName};host={$Host};&amp;quot;, $Username, $Password);&lt;br /&gt;
    } catch (Exception $e) {&lt;br /&gt;
        trigger_error(&amp;quot;PDO connection error: &amp;quot; . $e-&amp;gt;getMessage());&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SQL($Query) {&lt;br /&gt;
        global $DB;&lt;br /&gt;
        $args = func_get_args();&lt;br /&gt;
        if (count($args) == 1) {&lt;br /&gt;
            $result = $DB-&amp;gt;query($Query);&lt;br /&gt;
            if ($result-&amp;gt;rowCount()) {&lt;br /&gt;
                return $result-&amp;gt;fetchAll(PDO::FETCH_ASSOC);&lt;br /&gt;
            }&lt;br /&gt;
            return null;&lt;br /&gt;
        } else {&lt;br /&gt;
            if (!$stmt = $DB-&amp;gt;prepare($Query)) {&lt;br /&gt;
                $Error = $DB-&amp;gt;errorInfo();&lt;br /&gt;
                trigger_error(&amp;quot;Unable to prepare statement: {$Query}, reason: {$Error[2]}&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            array_shift($args); //remove $Query from args&lt;br /&gt;
            $i = 0;&lt;br /&gt;
            foreach ($args as &amp;amp;$v)&lt;br /&gt;
                $stmt-&amp;gt;bindValue(++$i, $v);&lt;br /&gt;
            $stmt-&amp;gt;execute();&lt;br /&gt;
            return $stmt-&amp;gt;fetchAll(PDO::FETCH_ASSOC);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 $res=SQL(&amp;quot;SELECT * FROM users WHERE ID&amp;gt;? ORDER BY ? ASC LIMIT 5&amp;quot; , 5 , &amp;quot;Username&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
===Where prepared statements do not work===&lt;br /&gt;
The problem is, when you need to build dynamic queries, or need to set variables not supported as a prepared variable, or your database engine does not support prepared statements. For example, PDO MySQL does not support ? as LIMIT specifier. In these cases, you need to do two things:&lt;br /&gt;
&lt;br /&gt;
====Not Supported Fields====&lt;br /&gt;
When some field does not support binding (like LIMIT clause in PDO), you need to '''whitelist''' the data you're about to use. LIMIT always requires an integer, so cast the variable to an integer. ORDER BY needs a field name, so whitelist it with field names:&lt;br /&gt;
&lt;br /&gt;
    function whitelist($Needle,$Haystack)&lt;br /&gt;
    {&lt;br /&gt;
        if (!in_array($Needle,$Haystack))&lt;br /&gt;
                return reset($Haystack); //first element&lt;br /&gt;
        return $Needle;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $Limit = $_GET['lim'];&lt;br /&gt;
    $Limit = $Limit * 1; //type cast, integers are safe&lt;br /&gt;
&lt;br /&gt;
    $Order = $_GET['sort'];&lt;br /&gt;
    $Order=whitelist($Order,Array(&amp;quot;ID&amp;quot;,&amp;quot;Username&amp;quot;,&amp;quot;Password&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
This is very important. If you think you're tired and you rather blacklist than whitelist, you're bound to fail.&lt;br /&gt;
&lt;br /&gt;
====Dynamic Queries====&lt;br /&gt;
Now this is a highly delicate situation. Whenever hackers fail to injection SQL in your common application scenarios, they go for Advanced Search features or similars, because those features rely on dynamic queries and dynamic queries are almost always insecurely implemented.&lt;br /&gt;
&lt;br /&gt;
When you're building a dynamic query, the only way is whitelisting. Whitelist every field name, every boolean operator (it should be OR or AND, nothing else) and after building your query, use prepared statements:&lt;br /&gt;
&lt;br /&gt;
    $Query=&amp;quot;SELECT * FROM table WHERE &amp;quot;;&lt;br /&gt;
    foreach ($_GET['fields'] as $g)&lt;br /&gt;
        $Query.=whitelist($g,Array(&amp;quot;list&amp;quot;,&amp;quot;of&amp;quot;,&amp;quot;possible&amp;quot;,&amp;quot;fields&amp;quot;,&amp;quot;here&amp;quot;)).&amp;quot;=?&amp;quot;;&lt;br /&gt;
    $Values=$_GET['values'];&lt;br /&gt;
    array_unshift($Query); //add to the beginning&lt;br /&gt;
    $res=call_user_func_array(SQL, $Values);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==ORM==&lt;br /&gt;
ORMs (Object Relational Mappers) are good security practice. If you're using an ORM (like [http://www.doctrine-project.org/ Doctrine]) in your PHP project, you're still prone to SQL attacks. Although injecting queries in ORM's is much harder, keep in mind that concatenating ORM queries makes for the same flaws that concatenating SQL queries, so '''NEVER''' concatenate strings sent to a database. ORM's support prepared statements as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Other Injection Cheat Sheet=&lt;br /&gt;
SQL aside, there are a few more injections possible ''and common'' in PHP:&lt;br /&gt;
&lt;br /&gt;
==Shell Injection==&lt;br /&gt;
A few PHP functions namely&lt;br /&gt;
&lt;br /&gt;
* shell_exec&lt;br /&gt;
* exec&lt;br /&gt;
* passthru&lt;br /&gt;
* system&lt;br /&gt;
* [http://no2.php.net/manual/en/language.operators.execution.php backtick operator] ( ` )&lt;br /&gt;
&lt;br /&gt;
run a string as shell scripts and commands. Input provided to these functions (specially backtick operator that is not like a function). Depending on your configuration, shell script injection can cause your application settings and configuration to leak, or your whole server to be hijacked. This is a very dangerous injection and is somehow considered the haven of an attacker.&lt;br /&gt;
&lt;br /&gt;
Never pass tainted input to these functions - that is input somehow manipulated by the user - unless you're absolutely sure there's no way for it to be dangerous (which you never are without whitelisting). Escaping and any other countermeasures are ineffective, there are plenty of vectors for bypassing each and every one of them; don't believe what novice developers tell you. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code Injection==&lt;br /&gt;
All interpreted languages such as PHP, have some function that accepts a string and runs that in that language. It is usually named Eval. PHP also has Eval.&lt;br /&gt;
Using Eval is a very bad practice, not just for security. If you're absolutely sure you have no other way but eval, use it without any tainted input.&lt;br /&gt;
&lt;br /&gt;
Reflection also could have code injection flaws. Refer to the appropriate reflection documentations, since it is an advanced topic.&lt;br /&gt;
 &lt;br /&gt;
==Other Injections==&lt;br /&gt;
LDAP, XPath and any other third party application that runs a string, is vulnerable to injection. Always keep in mind that some strings are not data, but commands and thus should be secure before passing to third party libraries.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=XSS Cheat Sheet=&lt;br /&gt;
&lt;br /&gt;
There are two scenarios when it comes to XSS, each one to be mitigated accordingly:&lt;br /&gt;
&lt;br /&gt;
==No Tags==&lt;br /&gt;
Most of the time, output needs no HTML tags. For example when you're about to dump a textbox value, or output user data in a cell. In this scenarios, you can mitigate XSS by simply using the function below. '''Keep in mind that this scenario won't mitigate XSS when you use user input in dangerous elements (style, script, image's src, a, etc.)''', but mostly you don't. Also keep in mind that every output that is not intended to contain HTML tags should be sent to the browser filtered with the following function.&lt;br /&gt;
&lt;br /&gt;
 //xss mitigation functions&lt;br /&gt;
 function xssafe($data,$encoding='UTF-8')&lt;br /&gt;
 {&lt;br /&gt;
 	return htmlspecialchars($data,ENT_QUOTES | ENT_HTML401,$encoding);&lt;br /&gt;
 }&lt;br /&gt;
 function xecho($data)&lt;br /&gt;
 {&lt;br /&gt;
 	echo xssafe($data);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 //usage example&lt;br /&gt;
 &amp;lt;input type='text' name='test' value='&amp;lt;?php &lt;br /&gt;
 xecho (&amp;quot;' onclick='alert(1)&amp;quot;);&lt;br /&gt;
 ?&amp;gt;' /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Yes Tags==&lt;br /&gt;
When you need tags in your output, such as rich blog comments, forum posts, blog posts and etc., you have to use a '''Secure Encoding''' library. This is usually hard and slow, and that's why most applications have XSS vulnerabilities in them. OWASP ESAPI has a bunch of codecs for encoding different sections of data. There's also OWASP AntiSammy and HTMLPurifier for PHP. Each of these require lots of configuration and learning to perform well, but you need them when you want that good of an application.&lt;br /&gt;
&lt;br /&gt;
==Templating engines==&lt;br /&gt;
&lt;br /&gt;
There are several templating engines that can help the programmer (and designer) to output data without exposing it too much against XSS vulnerabilities. While their primary goal isn't security, but improving the designing experience, most important templating engines automatically escape the variables on output and force the developer to explicitly indicate if there is a variable that shouldn't be escaped. This makes output of variables have a white-list behavior. There exist several of these engines. A good example is twig[http://twig.sensiolabs.org/]. Other popular template engines are Smarty, Haanga and Rain TPL.&lt;br /&gt;
&lt;br /&gt;
The advantage of following a white-list approach is that the programmer should be less prone to forget about using a function call to clean the output of a variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Other Tips==&lt;br /&gt;
&lt;br /&gt;
* We don't have a '''trusted section''' in any web application. Many developers tend to leave admin areas out of XSS mitigation, but most intruders are interested in admin cookies and XSS. Every output should be cleared by the functions provided above, if it has a variable in it. Remove every instance of echo, print, and printf from your application and replace them with the above statement when you see a variable is included, no harm comes with that.&lt;br /&gt;
&lt;br /&gt;
* HTTP-Only cookies are a very good practice, for a near future when every browser is compatible. Start using them now. (See PHP.ini configuration for best practice)&lt;br /&gt;
&lt;br /&gt;
* The function declared above, only works for valid HTML syntax. If you put your Element Attributes without quotation, you're doomed. Go for valid HTML.&lt;br /&gt;
&lt;br /&gt;
* [[Reflected XSS]] is as dangerous as normal XSS, and usually comes at the most dusty corners of an application. Seek it and mitigate it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=CSRF Cheat Sheet=&lt;br /&gt;
CSRF mitigation is easy in theory, but hard to implement correctly. First, a few tips about CSRF:&lt;br /&gt;
&lt;br /&gt;
* Every request that does something noteworthy, should be CSRF mitigated. Noteworthy things are changes to the system, and reads that take a long time.&lt;br /&gt;
* CSRF mostly happens on GET, but is easy to happen on POST. Don't ever think that post is secure.&lt;br /&gt;
&lt;br /&gt;
The [[PHP_CSRF_Guard|OWASP PHP CSRFGuard]] is a code snippet that shows how to mitigate CSRF. Only copy pasting it is not enough. In the near future, a copy-pasteable version  would be available (hopefully). For now, mix that with the following tips:&lt;br /&gt;
&lt;br /&gt;
* Use re-authentication for critical operations (change password, recovery email, etc.)&lt;br /&gt;
* If you're not sure whether your operation is CSRF proof, consider adding CAPTCHAs (however CAPTCHAs are inconvenience for users)&lt;br /&gt;
* If you're performing operations based on other parts of a request (neither GET nor POST) e.g Cookies or HTTP Headers, you might need to add CSRF tokens there as well.&lt;br /&gt;
* AJAX powered forms need to re-create their CSRF tokens. Use the function provided above (in code snippet) for that and never rely on Javascript.&lt;br /&gt;
* CSRF on GET or Cookies will lead to inconvenience, consider your design and architecture for best practices.&lt;br /&gt;
&lt;br /&gt;
=Authentication and Session Management Cheat Sheet=&lt;br /&gt;
PHP doesn't ship with a readily available authentication module, you need to implement your own or use a PHP framework, unfortunately most PHP frameworks are far from perfect in this manner, due to the fact that they are developed by open source developer community rather than security experts. A few instructive and useful tips are listed below:&lt;br /&gt;
 &lt;br /&gt;
==Session Management==&lt;br /&gt;
PHP's default session facilites are considered safe, the generated PHPSessionID is random enough, but the storage is not necessarily safe:&lt;br /&gt;
&lt;br /&gt;
* Session files are stored in temp (/tmp) folder and are world writable unless suPHP installed, so any LFI or other leak might end-up manipulating them.&lt;br /&gt;
* Sessions are stored in files in default configuration, which is terribly slow for highly visited websites. You can store them on a memory folder (if UNIX).&lt;br /&gt;
* You can implement your own session mechanism, without ever relying on PHP for it. If you did that, store session data in a database. You could use all, some or none of the PHP functionality for session handling if you go with that.&lt;br /&gt;
&lt;br /&gt;
===Session Hijacking Prevention===&lt;br /&gt;
It is good practice to bind sessions to IP addresses, that would prevent most session hijacking scenarios (but not all), however some users might use anonymity tools (such as TOR) and they would have problems with your service.&lt;br /&gt;
&lt;br /&gt;
To implement this, simply store the client IP in the session first time it is created, and enforce it to be the same afterwards. The code snippet below returns client IP address:&lt;br /&gt;
&lt;br /&gt;
 $IP = (getenv ( &amp;quot;HTTP_X_FORWARDED_FOR&amp;quot; )) ? getenv ( &amp;quot;HTTP_X_FORWARDED_FOR&amp;quot; ) : getenv ( &amp;quot;REMOTE_ADDR&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Keep in mind that in local environments, a valid IP is not returned, and usually the string ''':::1''' or ''':::127''' might pop up, thus adapt your IP checking logic.&lt;br /&gt;
&lt;br /&gt;
===Invalidate Session ID===&lt;br /&gt;
You should invalidate (unset cookie, unset session storage, remove traces) of a session whenever a violation occurs (e.g 2 IP addresses are observed). A log event would prove useful. Many applications also notify the logged in user (e.g GMail).&lt;br /&gt;
&lt;br /&gt;
===Rolling of Session ID===&lt;br /&gt;
You should roll session ID whenever elevation occurs, e.g when a user logs in, the session ID of the session should be changed, since it's importance is changed.&lt;br /&gt;
&lt;br /&gt;
===Exposed Session ID===&lt;br /&gt;
Session IDs are considered confidential, your application should not expose them anywhere (specially when bound to a logged in user). Try not to use URLs as session ID medium.&lt;br /&gt;
&lt;br /&gt;
Transfer session ID over TLS whenever session holds confidential information, otherwise a passive attacker would be able to perform session hijacking.&lt;br /&gt;
&lt;br /&gt;
===Session Fixation===&lt;br /&gt;
Session IDs are to be generated by your application only. Never create a session only because you receive the session ID from the client, the only source of creating a session should be a secure random generator.&lt;br /&gt;
&lt;br /&gt;
===Session Expiration===&lt;br /&gt;
A session should expire after a certain amount of inactivity, and after a certain time of activity as well. The expiration process means invalidating and removing a session, and creating a new one when another request is met.&lt;br /&gt;
&lt;br /&gt;
Also keep the '''log out''' button close, and unset all traces of the session on log out.&lt;br /&gt;
&lt;br /&gt;
====Inactivity Timeout====&lt;br /&gt;
Expire a session if current request is X seconds later than the last request. For this you should update session data with time of the request each time a request is made. The common practice time is 30 minutes, but highly depends on application criteria. &lt;br /&gt;
&lt;br /&gt;
This expiration helps when a user is logged in on a publicly accessible machine, but forgets to log out. It also helps with session hijacking.&lt;br /&gt;
&lt;br /&gt;
====General Timeout====&lt;br /&gt;
Expire a session if current session has been active for a certain amount of time, even if active. This helps keeping track of things. The amount differs but something between a day and a week is usually good. To implement this you need to store start time of a session.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cookies===&lt;br /&gt;
Handling cookies in a PHP script has some tricks to it:&lt;br /&gt;
&lt;br /&gt;
====Never Serialize====&lt;br /&gt;
Never serialize data stored in a cookie. It can easily be manipulated, resulting in adding variables to your scope.&lt;br /&gt;
&lt;br /&gt;
====Proper Deletion====&lt;br /&gt;
To delete a cookie safely, use the following snippet:&lt;br /&gt;
&lt;br /&gt;
 setcookie ($name, &amp;quot;&amp;quot;, 1);&lt;br /&gt;
 setcookie ($name, false);&lt;br /&gt;
 unset($_COOKIE[$name]);&lt;br /&gt;
The first line ensures that cookie expires in browser, the second line is the standard way of removing a cookie (thus you can't store false in a cookie). The third line removes the cookie from your script. Many guides tell developers to use time() - 3600 for expiry, but it might not work if browser time is not correct.&lt;br /&gt;
&lt;br /&gt;
You can also use '''session_name()''' to retrieve the name default PHP session cookie.&lt;br /&gt;
&lt;br /&gt;
====HTTP Only====&lt;br /&gt;
Most modern browsers support HTTP-only cookies. These cookies are only accessible via HTTP(s) requests and not Javascript, so XSS snippets can not access them. They are very good practice, but are not satisfactory since there are many flaws discovered in major browsers that lead to exposure of HTTP only cookies to javascript.&lt;br /&gt;
&lt;br /&gt;
To use HTTP-only cookies in PHP (5.2+), you should perform session cookie setting [http://php.net/manual/en/function.setcookie.php manually] (not using '''session_start'''):&lt;br /&gt;
 &lt;br /&gt;
 #prototype&lt;br /&gt;
 bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )&lt;br /&gt;
&lt;br /&gt;
 #usage&lt;br /&gt;
 if (!setcookie(&amp;quot;MySessionID&amp;quot;, $secureRandomSessionID, $generalTimeout, $applicationRootURLwithoutHost, NULL, NULL,true))&lt;br /&gt;
     echo (&amp;quot;could not set HTTP-only cookie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The '''path''' parameter sets the path which cookie is valid for, e.g if you have your website at example.com/some/folder the path should be /some/folder or other applications residing at example.com could also see your cookie. If you're on a whole domain, don't mind it. '''Domain''' parameter enforces the domain, if you're accessible on multiple domains or IPs ignore this, otherwise set it accordingly. If '''secure''' parameter is set, cookie can only be transmitted over HTTPS. See the example below:&lt;br /&gt;
&lt;br /&gt;
 $r=setcookie(&amp;quot;SECSESSID&amp;quot;,&amp;quot;1203j01j0s1209jw0s21jxd01h029y779g724jahsa9opk123973&amp;quot;,time()+60*60*24*7 /*a week*/,&amp;quot;/&amp;quot;,&amp;quot;owasp.org&amp;quot;,true,true);&lt;br /&gt;
 if (!$r) die(&amp;quot;Could not set session cookie.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
====Internet Explorer issues====&lt;br /&gt;
Many version of Internet Explorer tend to have problems with cookies. Mostly setting Expire time to 0 fixes their issues.&lt;br /&gt;
&lt;br /&gt;
==Authentication==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Remember Me===&lt;br /&gt;
Many websites are vulnerable on remember me features. The correct practice is to generate a one-time token for a user and store it in the cookie. The token should also reside in data store of the application to be validated and assigned to user. This token should have '''no relevance''' to username and/or password of the user, a secure long-enough random number is a good practice.&lt;br /&gt;
&lt;br /&gt;
It is better if you imply locking and prevent brute-force on remember me tokens, and make them long enough, otherwise an attacker could brute-force remember me tokens until he gets access to a logged in user without credentials.&lt;br /&gt;
&lt;br /&gt;
* '''Never store username/password or any relevant information in the cookie.'''&lt;br /&gt;
&lt;br /&gt;
=Access Control Cheat Sheet=&lt;br /&gt;
This section aims to mitigate access control issues, as well as '''Insecure Direct Object Reference''' issues. &lt;br /&gt;
&lt;br /&gt;
=Cryptography Cheat Sheet=&lt;br /&gt;
&lt;br /&gt;
=File Inclusion Cheat Sheet=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Configuration and Deployment Cheat Sheet=&lt;br /&gt;
Please see [[PHP Configuration Cheat Sheet]].&lt;br /&gt;
&lt;br /&gt;
=Sources of Taint=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OLD. PHP General Guidelines for Secure Web Applications  =&lt;br /&gt;
&lt;br /&gt;
== PHP Version ==&lt;br /&gt;
Use '''PHP 5.3.8'''. Stable versions are always safer then the beta ones. &lt;br /&gt;
&lt;br /&gt;
== Framework==&lt;br /&gt;
Use a framework like '''Zend''' or '''Symfony'''. Try not to re-write the code again and again. Also avoid dead codes. &lt;br /&gt;
&lt;br /&gt;
== Directory==&lt;br /&gt;
Code with most of your code outside of the webroot. This is automatic for Symfony and Zend. Stick to these frameworks. &lt;br /&gt;
&lt;br /&gt;
== Hashing Extension ==&lt;br /&gt;
Not every PHP installation has a working '''mhash''' extension, so if you need to do hashing, check it before using it. Otherwise you can't do SHA-256&lt;br /&gt;
&lt;br /&gt;
== Cryptographic Extension ==&lt;br /&gt;
Not every PHP installation has a working '''mcrypt''' extension, and without it you can't do AES. Do check if you need it.&lt;br /&gt;
&lt;br /&gt;
== Authentication and Authorization ==&lt;br /&gt;
There is no authentication or authorization classes in native PHP. Use '''ZF''' or '''Symfony''' instead.&lt;br /&gt;
&lt;br /&gt;
== Input nput validation ==&lt;br /&gt;
Use $_dirty['foo'] = $_GET['foo'] and then $foo = validate_foo($dirty['foo']); &lt;br /&gt;
&lt;br /&gt;
== Use PDO or ORM ==&lt;br /&gt;
Use PDO with prepared statements or an ORM like Doctrine&lt;br /&gt;
&lt;br /&gt;
== Use PHP Unit and Jenkins ==&lt;br /&gt;
When developing PHP code, make sure you develop with PHP Unit and Jenkins - see http://qualityassuranceinphpprojects.com/pages/tools.html for more details.&lt;br /&gt;
&lt;br /&gt;
== Use Stefan Esser's Hardened PHP Patch ==&lt;br /&gt;
Consider using Stefan Esser's Hardened PHP patch - http://www.hardened-php.net/suhosin/index.html &lt;br /&gt;
(not maintained now, but the concepts are very powerful)&lt;br /&gt;
&lt;br /&gt;
== Avoid Global Variables==&lt;br /&gt;
In terms of secure coding with PHP, do not use globals unless absolutely necessary &lt;br /&gt;
Check your php.ini to ensure register_globals is off Do not run at all with this setting enabled It's extremely dangerous (register_globals has been disabled since 5.0 / 2006, but .... most PHP 4 code needs it, so many hosters have it turned on)&lt;br /&gt;
&lt;br /&gt;
== Avoid Eval() ==&lt;br /&gt;
It basically allows arbitrary PHP code execution, so do not evaluate user supplied input. and if you're not doing that, you can just use PHP directly. eval() is at least 10-100 times slower than native PHP&lt;br /&gt;
&lt;br /&gt;
== Protection against RFI==&lt;br /&gt;
Ensure allow_url_fopen and allow_url_include are both disabled to protect against RFI  But don't cause issues by using the pattern include $user_supplied_data or require &amp;quot;base&amp;quot; + $user_supplied_data - it's just unsafe as you can input /etc/passwd and PHP will try to include it&lt;br /&gt;
&lt;br /&gt;
== Regexes (!)==&lt;br /&gt;
Watch for executable regexes (!) &lt;br /&gt;
&lt;br /&gt;
== Session Rotation ==&lt;br /&gt;
Session rotation is very easy - just after authentication, plonk in session_regenerate_id() and you're done.&lt;br /&gt;
&lt;br /&gt;
== Be aware of PHP filters ==&lt;br /&gt;
PHP filters can be tricky and complex. Be extra-conscious when using them. &lt;br /&gt;
&lt;br /&gt;
== Logging ==&lt;br /&gt;
Set display_errors to 0, and set up logging to go to a file you control, or at least syslog. This is the most commonly neglected area of PHP configuration&lt;br /&gt;
&lt;br /&gt;
== Output encoding ==&lt;br /&gt;
Output encoding is entirely up to you. Just do it, ESAPI for PHP is ready for this job.&lt;br /&gt;
&lt;br /&gt;
These are transparent to you and you need to know about them. php://input: takes input from the console gzip: takes compressed input and might bypass input validation http://au2.php.net/manual/en/filters.php &lt;br /&gt;
&lt;br /&gt;
= Authors and Primary Editors  =&lt;br /&gt;
&lt;br /&gt;
[[User:Abbas Naderi|Abbas Naderi Afooshteh]] ([mailto:abbas.naderi@owasp.org abbas.naderi@owasp.org])&lt;br /&gt;
&lt;br /&gt;
[[User:Achim|Achim]] - [mailto:achim_at_owasp.org Achim at owasp.org]&lt;br /&gt;
&lt;br /&gt;
[mailto:vanderaj@owasp.org Andrew van der Stock]&lt;br /&gt;
&lt;br /&gt;
= Other Cheatsheets =&lt;br /&gt;
{{Cheatsheet_Navigation}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Cheatsheets]]&lt;/div&gt;</summary>
		<author><name>Simon Waters</name></author>	</entry>

	</feed>