Ampersands, PHP Sessions e HTML válido

Esta é a tradução do artigo "Ampersands, PHP Sessions and Valid HTML?" de autoria de David Dorward publicado no site do W3C.

1. A versão oficial e original, em inglês, deste tutorial, encontra-se em:http://www.w3.org/QA/2005/04/php-session e os seus direitos são conforme:

Copyright ©2002 W3C® (MIT, INRIA, Keio), Todos os direitos reservados. São aplicáveis as disposições do W3C relativas a responsabilidade, marcas, uso de documentos e licença de software

2. A única versão oficial deste documento é a versão em língua inglesa que se encontra no sítio do W3C.

3. O presente documento traduzido para a língua portuguesa do Brasil, pode conter erros de tradução.

Este documento foi traduzido em 15 de novembro de 2008 por: Maurício Samy Silva.
A traduçao foi feita somente para este documento, vale dizer, as páginas remetidas pelos links aqui indicados, estão em sua versão original em língua inglesa.

O porquê do uso de PHP sessions resultar em uma marcação HTML e XHTML inválidas e como corrigir isto.

Status deste documento

Este documento é uma contribuição do QA Interest Group. Feedback, sugestões e correções são bem-vindas e devem ser encaminhadas para a lista de discussão www-qa.

Créditos

Autor(es)
David Dorward

Índice

Background

Em HTML (e XHTML, e nas aplicações SGML e XML) determinados caracteres têm um significado especial, como por exemplo, o sinal "menor que" <, que indica a abertura de uma tag. Se você pretende que caracteres como este sejam renderizados ou apresentados de uma forma qualquer, não pode simplesmente digitá-los no seu documento - senão, como um agente de usuário saberia a diferença entre b<a (significando b é menor do que a) e b<a (significando b seguido da tag de abertura do elemento âncora)?

Para possibilitar a apresentação de caracteres reservados, tais como este, a HTML e XHTML possuem um mecanismo denominado character references. A sintaxe para escrita destes caracteres reservados é:

  1. um ampersand (e-comercial)
  2. um "código" para o caractere
  3. um ponto-e-vírgula

Por exemplo, o caractere "menor que " tem a seguinte sintaxe que o representa: &lt;.

Usando o ampersand na sintaxe para representar caracteres reservados, como mostrado para < , faz com que haja necessidade de uma sintaxe especial para escrever o ampersand em documentos e esta representação é: - &amp;

É bom ressaltar que há excessões a esta sintaxe, mas elas são irrelevantes quando tratamos de questões relacionadas a PHP sessions.

HTML e XHTML prevêem o uso de blocos de códigos chamados CDATA, dentro dos quais os caracteres especiais da HTML perdem seus significados especiais. Códigos escritos dentro de tais blocos não são processados e assim um ampersand pode ser digitado normalmente sem uso da sintaxe mostrada anteriormente. Em HTML, os conteúdos dentro dos elementos <script> e <style> são CDATA, enquanto que em XHTML não são, ver (they are marked explicitly). Nestes casos você pode evitar problemas colocando as folhas de estilo e scripts em arquivos externos e linkando-os ao documento com uso do elemento <link> e da marcação <script src="…"> respectivamente.

Há excessões e por vezes tanto o uso do ponto-e-vírgula como a codificação do ampersand é opcional. Em tais situações é melhor optar pelo uso do ponto-e-vírgula e da codificação do ampersand. Dito isto, não entrarei em maiores detalhes sobre estes casos opcionais.

Problema

PHP session é uma funcionalidade nativa da linguagem que possibilita armazenar dados no servidor para serem associados a um determinado usuário (por exemplo: um visitante do site).

A associação dos dados ao usuário é feita com uso de fragmentos identificadores chamados genericamente de tokens. Tokens são armazenados em cookie, mas nem todos os agentes de usuário suportam cookies e a maioria dos que os suportam, permitem que eles sejam desabilitados ou apagados.

PHP possui um mecanismo alternativo para tais situações. Se cookies não forem aceitos no lado do cliente cada link da página é reescrito de modo a incluir os tokens em uma query string. Eu acredito que este mecanismo é habilitado por padrão, contudo testes realizados com o pacote Fedora do PHP 4.3.11 (Fedora release 2.4) demostraram que o mecanismo não estava habilitado. Ele pode ser configurado na diretiva session.trans_sid.

Isto, em teoria, é uma solução elegante para o problema (resalvados alguns casos relacionados a computadores públicos, compartilhamento de links, etc), mas apresenta algumas falhas.

Para links que não são com uma query string não há problemas. PHP acrescenta ?PHPSESSID= seguido por um número hexadecimal randômico. Para links que são com uma query string PHP acrescenta &PHPSESSID=.

Os caracteres ampersands usados como separadores de argumentos não causam problemas nas URLs textuais antigas, contudo em URLs codificadas como HTML os ampersands são interpretados como uma referência ao início de codificação de caractere (a menos de excessões já mencionadas) e em consequência torna inválida a sintaxe mostrada no parágrafo anterior.

A maioria dos usuários não tomarão conhecimento do problema e os agentes de usuários, projetados para interpretar e corrigir os erros cometidos pelo autor do documento, também irão ignorar o problema.

Soluções

Referência para codificação de caracteres

O caractere que o PHP usa para separar argumentos é configurável com a diretiva arg_separator.output. Ele pode ser configurado de várias formas e esta é a solução sugerida no manual do PHP.

Editando php.ini

O arquivo php.ini contém os dados centrais de instalação do PHP em um computador. Neste arquivo você você pode especificar um caracter de referência para codificar caracteres como mostrado a seguir.

arg_separator.output = "&amp;"

Diretivas do Apache

O servidor Apache admite configurações por scripts PHP em locais pré-determinados. Isto possibilita configurar diferentes diretivas para um site ou para um diretório (por exemplo um bloco <location> ou um arquivo .htaccess).

php_value arg_separator.output &amp;

Configuração por script

As diretivas de configuração do PHP podem ser configuradas por scripts em um conjunto de funções (the ini_set function). Coloque o código de configuração das diretivas logo no início do script.

<?php ini_set('arg_separator.output','&amp;'); ?>

Usando um separador de argumentos alternativo

Uma vez que o caractere ampersand tem um significado especial em HTML, as especificações sugerem que os parses reconheçam o ponto-e-vírgula como um separador de argumentos em uma query string (use of a semicolon as an argument separator). PHP vem pré-configurado para aceitar o ponto-e-vírgula como separador de argumentos e as mesmas técnicas descritas anteriormente são válidas, como mostrado a seguir.

Editando php.ini

arg_separator.output = ";"

Diretiva Apache

php_value arg_separator.output ;

Configuração por script

<?php ini_set('arg_separator.output',';'); ?>

Desabilitando sessions para usuários non-cookie

Esta opção tem uma série de vantagens sobre o ponto de vista da segurança uma vez que reduz as chances de um token ser acessado por terceiros. Por outro lado o código para session torna-se ineficaz para usuários que desabilitem, não suportem ou bloqueiem (isto acarreta problemas com a acessibilidade).

Editando php.ini

session.use_trans_sid = 0

Diretiva Apache

php_value session.use_trans_sid 0

Configuração por script

Esta opção depende da versão do PHP. Caso seja possível configurar a sintaxe é a mostrada a seguir:

<?php ini_set('session.use_trans_sid','0'); ?>

Valid XHTML 1.0!
Created Date: 2005-04-15
Last modified $Date: 2005/07/11 14:35:58 $ by $Author: ot $

Copyright © 2000-2003 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply. Your interactions with this site are in accordance with our public and Member privacy statements.