Expor suas chaves primárias (especialmente se elas forem previsíveis) é uma vulnerabilidade chamada Insecure Direct Object Reference.
Por ter um URL (ou qualquer outro parâmetro fornecido pelo cliente) como este:
http://www.domain.com/myaccount?userid=12
Você dá a seus usuários finais a oportunidade de mexer com essas variáveis e passar quaisquer dados que eles gostem. A contramedida para mitigar essa vulnerabilidade é criar referências de objeto indiretas. Isso pode soar como uma grande mudança, mas não necessariamente tem que ser. Você não precisa redigitar todas as suas tabelas ou qualquer coisa, você pode fazer isso apenas sendo inteligente com seus dados através do uso de um mapa de referência indireta.
Considere o seguinte:você tem um usuário que está fazendo uma compra em seu site. E quando é hora de pagar, eles são apresentados com uma lista suspensa dos números de cartão de crédito deles que você tem "arquivado". Se você observar o código da lista suspensa, verá que os números do cartão de crédito estão associados às chaves 8055, 9044 e 10099.
O usuário pode olhar para isso e pensar que elas se parecem muito com chaves primárias de incremento automático (o usuário provavelmente estaria certo). Então ele começa a tentar outras chaves para ver se consegue pagar com o cartão de outra pessoa.
Agora, tecnicamente, você deve ter um código no lado do servidor que garanta que o cartão selecionado faça parte da conta do usuário e que ele possa usá-lo. Este é um exemplo inventado. Por enquanto vamos supor que este não é o caso ou que este é outro tipo de formulário que talvez não tenha esse tipo de controle do lado do servidor.
Então, como evitamos que o usuário final escolha uma chave que não deveria estar disponível para ele?
Em vez de mostrar a eles uma referência direta ao registro no banco de dados, forneça a eles uma referência indireta.
Em vez de colocar as chaves do banco de dados no menu suspenso, criaremos um array no servidor e o colocaremos na sessão do usuário.
Array cards = new Array(3);
cards[0] = 8055;
cards[1] = 9044;
cards[2] = 10099;
Na lista suspensa, agora fornecemos a referência ao índice do array onde o cartão está armazenado. Portanto, em vez de ver as chaves reais, o usuário final verá os valores 0, 1 e 2, se visualizar a fonte.
Quando o formulário for enviado, um desses valores será repassado. Em seguida, retiramos o array da sessão do usuário e usamos o índice para obter o valor. A chave real nunca saiu do servidor.
E o usuário pode passar valores diferentes durante todo o dia, se quiser, mas nunca, jamais, obterá um resultado que não seja seus próprios cartões, independentemente do controle de acesso do lado do servidor em vigor.
Tenha em mente que, ao usar o índice passado para obter o valor, se o usuário mexer com ele, você poderá obter algumas exceções (ArrayOutOfBounds, InvalidIndex, o que for). Portanto, envolva essas coisas em um try/catch para que você possa suprimir esses erros e registrar as falhas para procurar tentativas de cracking.
Espero que isto ajude.
Para ler mais sobre Insecure Direct Object References, confira o OWASP Top 10. É o risco número A4. https://www.owasp.org/index.php/Top_10_2010-A4 -Insecure_Direct_Object_References