Jogo da Moeda

Eu sei que tenho de validar o conteúdo das variáveis também no PHP, e estou a tratar disso, agora só não estou a ver como vou actualizar o atributo "max" do slider com AJAX. Alguma sugestão?

http://www.phptherightway.com/#security
Básicamente a comunidade de PHP fartou-se da desinformação que existe na web sobre as melhores práticas, e tem feito esse site open-source para todos aprenderem...

Tinha-me esquecido completamente desse link, ate que a pouco alguem me o relembrou... Vou ver o teu slider com mais atenção agora...


edit: Link para um slider de exemplo http://jsfiddle.net/ZHEsh/
 
Última edição:
Obrigado pelo link, assim à primeira vista parece que este conteúdo me vai ajudar bastante. Falta-me perguntar uma coisa, eu criei um ligação permanente (por assim dizer) com o servidor para actualizar as "Últimas Apostas" e o "Top 5 de Jogadores" de 1 em 1 segundo. (Utilizei a expressão: setInterval("ajaxStats()",1000); ). A teu ver, achas isto incorrecto?
 
Última edição:
Obrigado pelo link, assim à primeira vista parece que este conteúdo me vai ajudar bastante. Falta-me perguntar uma coisa, eu criei um ligação permanente (por assim dizer) com o servidor para actualizar as "Últimas Apostas" e o "Top 5 de Jogadores" de 1 em 1 segundo. (Utilizei a expressão: setInterval("ajaxStats()",1000); ). A teu ver, achas isto incorrecto?

Essa técnica chama-se "pooling" e 1000 é um bocado puxado especialmente para algo que não precisa de ser recarregado assim tantas vezes.
Confesso que não sou grande fã, embora isso não esteja incorreto, recentemente começaram aparecer alternativas como ServerSide Events e WebSockets... talvez queiras pesquisar sobre elas, mas convinha já estares confortável com AJAX primeiro =)

Por outras palavras... é uma técnica algo ultrapassada, mas já foi muito útil, na realidade até há bastante pouco tempo, o chat do facebook funcionava assim.

O que deves evitar é "ajaxStats()" eu sei que maioria dos sites online, dizem para fazer os setInterval assim, mas isso não é mesmo correto.
o Javascript para perceber o que é essa string, tem de passar isso, implicitamente, pelo eval(), e 30s de pesquisa e reparas que em Javascript eval === evil

a forma correcta é:

Código:
setInterval(ajaxStats, 1000);

Já agora não se reparaste que acrescentei um link no meu comentário anterior...
 
Última edição:
Essa técnica chama-se "pooling" e 1000 é um bocado puxado especialmente para algo que não precisa de ser recarregado assim tantas vezes.
Confesso que não sou grande fã, embora isso não esteja incorreto, recentemente começaram aparecer alternativas como ServerSide Events e WebSockets... talvez queiras pesquisar sobre elas, mas convinha já estares confortável com AJAX primeiro =)

Por outras palavras... é uma técnica algo ultrapassada, mas já foi muito útil, na realidade até há bastante pouco tempo, o chat do facebook funcionava assim.

O que deves evitar é "ajaxStats()" eu sei que maioria dos sites online, dizem para fazer os setInterval assim, mas isso não é mesmo correto.
o Javascript para perceber o que é essa string, tem de passar isso, implicitamente, pelo eval(), e 30s de pesquisa e reparas que em Javascript eval === evil

a forma correcta é:

Código:
setInterval(ajaxStats, 1000);

Já agora não se reparaste que acrescentei um link no meu comentário anterior...

Fiz uma pequena pesquisa e descobri que realmente o javascript utiliza a função eval() para descobrir se uma string tem instruções de javascript. Agora só não entendo é como é que o javascript reconhece ajaxStats como uma função visto que para chamar-mos uma função temos de utilizar '()'.
Se eu fizesse isto:
setInterval(ajaxStats(), 1000);
Estaria incorrecto? Se sim porquê?

 
Ora bem... depois do Ryu^ me ter falado do teu caso, e me ter dito que fizeste validação javascript, decidi dar uma vista de olhos.

Como podes ver, tanto eu como ele estamos como administradores de novo e ainda estive a ver o que descobria das apostas, e eis as dicas que tenho para te dar:

As validações javascript que usaste, sozinhas, não servem de muito. O javascript corre no lado do cliente e pode ser alterado. Eu simplesmente apaguei os dois "ifs" que colocaste e o mysql injection corre 5*.

Solução? Simples. Uma validação que não possa ser alterada, ou seja, no php!
Quando estás a receber os dados no php ficas com, faz de conta
PHP:
$username = $_POST['username'];
E guardas na variável o valor que é enviado, certo? (Atencão que tanto o nome da variável como a key usada no POST são arbitrárias e servem para exemplo aqui.)

Ora agora, devias de ter uma validação como a que tinhas no javascript, mas desta vez aqui!
Podes optar pela solução que tinhas de encontrar valores não alfanuméricos, ou podes utilizar uma função que aconselho a googlares sobre ela chamada mysql_real_escape_string(). Existem outras maneiras de te protegeres contra estes ataques, umas mais avançadas que outras e então se entrares pelos lados do mysqli ainda mais tens para ver, mas começa pelo básico.

Por isso, resumidamente, aconselho algo do género...

PHP:
$username = $_POST['username'];
$username = mysql_real_escape_string($username);

Ou isso ou em vez da funcao de escape algo tipo isto:
PHP:
if ( ereg('[^a-zA-Z0-9]',$username) ) {
     //Não é alfanumérico, termina aqui o processamento com um exit e mensagem de erro ou como quiseres.
}

Se aplicares isto a todas as variáveis de entrada em principio estás safo.

Lembra-te deste principio: Tudo o que vem do utilizador, tu não controlas e pode ter "malicias" agarradas, logo há que desconfiar de tudo o que o utilizador possa enviar. Seja username. Seja password. Ou a aposta por exemplo. ;) Até a cara ou coroa pode ser manipulada.

Bom trabalho e continua! :)
Gosto de ver pessoas entusiasmadas com projectos destes.
 
AWRyder, obrigado pela dica. Eu já sabia que tinha de validar as variáveis dos input's no PHP e também sabia como fazê-lo, só não tive tempo porque tenho andado ocupado a ler a documentação da jQuery e da jQueryUi.
Se entenderes alguma coisa de javascript importaste de responder à minha questão acima?

Abraço!
 
Ele só precisa de saber o nome da função. Porque que vai receber uma função já sabe ele! é um bocado do género:
Ele pergunta-te qual o nome da função.
Tu dizes que é "xpto"
Ele procura o a função com esse nome e executa-a.

A questão é, ele também é inteligente ao ponto de saber se tu metes () e executa isso também perfeitamente. Aliás, se a função tiver parametros é assim que tens que fazer.

Algo tipo isto:

function startCalc(one, two, three){
interval = setInterval("calc('"+one+"', '"+two+"', '"+three+"')",1)
}
Nesse exemplo tens uma função calc que recebe 3 parametros. o One, Two e Three.
E repara que a setInterval agora não vai receber a função ( tu para enviares funções escreves o nome delas, ponto final paragrafo),
mas vai sim receber UMA STRING com o que queres executar. Ele aceita as duas maneiras.
Sendo que se enviares a string podes fazer como estavas a dizer, ou mais ou menos parecido, a unica diferença seria:
em vez de: AjaxStats()
ficaria: "AjaxStats()"
Se a função recebesse parametros:
"AjaxStats(1,2,'tres')"

Etc, etc.

Isto responde à pergunta? :P
 
À excepção do IE8 e inferiores, se quiseres passar argumentos para a função, so tens de os acrescentar:

Código:
​var lol = function (greet, who) {
    alert(greet +', '+ who);        
};
  
​setInterval(lol, 5000, "Hello", "World");​​​​​​​​

tal como o AWRyder disse, repara que so passei "lol" o nome da função... mas nao a chamei "lol()"

Se quiseres que funcione em IE8 ou inferiores e por acaso tiveres a usar jQuery (94% dos sites actuais tem...)

o mesmo exemplo fica

Código:
​var lol = function (greet, who) {
    alert(greet +', '+ who);        
};
  
​setInterval($.proxy(lol, this, "Hello", "World), 5000);

Agora... parem de por strings nos setInterval/setTimeouts, é mais lento, trocam o contexto do codigo, e evitam todas as optimizações que o os browsers vos poderiam dar de borla, pois o codigo na string tem de ser re-interpretado pelo browser...

A função ereg do PHP já não foi deprecated? =\
 
Última edição:
Sim, o ereg está deprecated. Mas repara que eu disse "algo tipo isto", até podia ter usado pseudo-código mas optei por um exemplo simples que encontrei e na altura nem reparei que era o ereg.

De qualquer forma, existe o preg_match que faz o mesmo e não está deprecated.
E quem fala no preg_match, fala no preg_replace e todos os outros irmãos, facilmente encontrados no php.net.

PS: A utilização de strings naquele contexto é um desenrasca, visto que o ImAnAlcoholic mostrou uma maneira em que não é preciso o script interpretar mais código desnecessáriamente, utiliza essa.
 
Última edição:
Hoje criei um sistema para ver quantos utilizadores têm sessão iniciada e validei todas as variáveis dos formulários no PHP. Não sei se ficou a faltar alguma coisa, por isso se conseguirem injectar SQL avisem.
 
Assim à primeira vista... Login e pass (no login e no registo), se é cara ou coroa e quanto se aposta, parecem-me a ser as únicas coisas que tens que te preocupar, pode-me ter faltado alguma coisa mas também não vi com muita atenção. Ah e ignorei os campos do admin panel, estamos a assumir que nenhum utilizador malicioso teria acesso à partida a esse menu.

Outra coisa que me lembrei, como estás a... ver se sai Cara ou Coroa? Que tipo de random estás a utilizar? Isto tem a haver com uma coisa que se pode considerar "mariquice" mas é facil de "complicar". :P Tem a haver com o prever o próximo sorteio. O que se torna ainda mais fácil visto que tens uns logs de se se perdeu ou ganhou.
 
Assim à primeira vista... Login e pass (no login e no registo), se é cara ou coroa e quanto se aposta, parecem-me a ser as únicas coisas que tens que te preocupar, pode-me ter faltado alguma coisa mas também não vi com muita atenção. Ah e ignorei os campos do admin panel, estamos a assumir que nenhum utilizador malicioso teria acesso à partida a esse menu.

Outra coisa que me lembrei, como estás a... ver se sai Cara ou Coroa? Que tipo de random estás a utilizar? Isto tem a haver com uma coisa que se pode considerar "mariquice" mas é facil de "complicar". :P Tem a haver com o prever o próximo sorteio. O que se torna ainda mais fácil visto que tens uns logs de se se perdeu ou ganhou.

Estou a utilizar a função mt_rand(0, 1); Sendo que se calhar 0 é cara 1 um é coroa. Achas possível prever com esta função?

Quanto ao painel de administração estou a tratar de verificar os privilégios antes de permitir o acesso à página.
 
Verdade seja dita eu nunca aprofundei muito este tópico.
Estive a ler um bocado sobre a mt_rand e vi que existe também uma mt_srand() onde podes dizer qual é a seed.

A ideia muito básica da coisa é: Imaginando que usas a seed "1234" e pedes 5 numeros entre 1-10, imagina que calha 5,6,7,8,9 (eu inventei os resultados para dar o exemplo)
A próxima vez que voltares a usar a mesma seed, os resultados seriam os mesmos, 5,6,7 etc etc. Ou seja, há um padrão.
Isto é uma hipótese muito remota mas imaginando que alguem detecta o padrão que estás a usar, pode determinar a seed e prever o próximo número.

Bem, como disse eu nunca entrei muito nisto, decidi deixar aqui a dica para o caso de quereres explorar isso. :P
 
Verdade seja dita eu nunca aprofundei muito este tópico.
Estive a ler um bocado sobre a mt_rand e vi que existe também uma mt_srand() onde podes dizer qual é a seed.

A ideia muito básica da coisa é: Imaginando que usas a seed "1234" e pedes 5 numeros entre 1-10, imagina que calha 5,6,7,8,9 (eu inventei os resultados para dar o exemplo)
A próxima vez que voltares a usar a mesma seed, os resultados seriam os mesmos, 5,6,7 etc etc. Ou seja, há um padrão.
Isto é uma hipótese muito remota mas imaginando que alguem detecta o padrão que estás a usar, pode determinar a seed e prever o próximo número.

Bem, como disse eu nunca entrei muito nisto, decidi deixar aqui a dica para o caso de quereres explorar isso. :P


Isso é de facto uma curiosidade engraçada na programação... A maioria das funções de random, são na realidade pseudo-random number generators, ou seja, baseam-se numa seed (como por exemplo o relógio do sistema) para criar a ilusão de aleatoriedade. Para 99% dos casos, isso é mais que suficiente... Mas se o teu jogo envolvesse dinheiro real, eu pessoalmente não correria esse risco... =P

Um exemplo prático e inofensivo do problema que o AWRyder tava a dizer: http://apple.stackexchange.com/questions/23194/why-isnt-itunes-shuffle-random
 
Isso é de facto uma curiosidade engraçada na programação... A maioria das funções de random, são na realidade pseudo-random number generators, ou seja, baseam-se numa seed (como por exemplo o relógio do sistema) para criar a ilusão de aleatoriedade. Para 99% dos casos, isso é mais que suficiente... Mas se o teu jogo envolvesse dinheiro real, eu pessoalmente não correria esse risco... =P

Um exemplo prático e inofensivo do problema que o AWRyder tava a dizer: http://apple.stackexchange.com/questions/23194/why-isnt-itunes-shuffle-random

Quase de certeza que conheces os serviços que sorteiam números (por exemplo o http://www.random.org/), sabes como funciona esse tipo de random?

EDIT: Que intervalo de tempo me aconselhas entre cada pedido de AJAX ao servidor (Pooling)?

Abraço!
 
Última edição:
Quase de certeza que conheces os serviços que sorteiam números (por exemplo o http://www.random.org/), sabes como funciona esse tipo de random?

Existem algumas formas, mas a maioria delas (ou pelo menos todas as que conheço, pode haver outras…) necessitam de um equipamento de hardware especial, ou para medir a electricidade estática, ou reflecção/refracção de fotões ou medições de radiação... seja como for, a filosofia passa por medir um evento físico…

No caso especifico do random.org eles usam um rádio para medir variações da amplitudo do ruido atmosférico... este artigo pode-te iluminar um bocado: http://en.wikipedia.org/wiki/Random_number_generation#Physical_methods

Como te disse, preocupa-te em teres algo minimamente aleatorio, em vez de algo *realmente* aleatório. Estás a fazer um jogo por diversão, e não tens dinheiro real envolvido. =P
Por outro lado se realmente quiseres... podes usar a API do random.org para ir buscar numeros aleatorios =P http://www.random.org/clients/http/
 
Bem, depois de muito tempo a tentar tratar disto lá consegui o que queria.
Como, muitos disseram, só fizeste a validação de algumas coisas no lado do cliente consegui apostar dinheiro negativo.
O que acontece é que quando perco, perco "-10€", ou seja, ganho 10€
semttulogfr.png

Resultado final:
semttuloqrs.png


Já agora, no registo e login estás a enviar a password por GET o que faz com que qualquer sniffer ou pessoa a olhar para o ecra consiga ver a pass.
 
Última edição:
Bem, depois de muito tempo a tentar tratar disto lá consegui o que queria.
Como, muitos disseram, só fizeste a validação de algumas coisas no lado do cliente consegui apostar dinheiro negativo.
O que acontece é que quando perco, perco "-10€", ou seja, ganho 10€
semttulogfr.png

Resultado final:
semttuloqrs.png


Já agora, no registo e login estás a enviar a password por GET o que faz com que qualquer sniffer ou pessoa a olhar para o ecra consiga ver a pass.

Por acaso, eu validei as apostas de valor 0, mas tinha-me esquecido de validar as apostas negativas, mas agora já actualizei o código e penso que esse bug está resolvido.
Quanto ao login ele é feito via AJAX e por isso não é mostrada nem a password nem o utilizador na URL, por outro lado, na página registo, os parâmetros são passados na URLce ai sim tens razão mas estou a tratar desse assunto, em breve estará disponível o registo via AJAX.

Abraço e obrigado por reportares esse BUG.
 
Por acaso, eu validei as apostas de valor 0, mas tinha-me esquecido de validar as apostas negativas, mas agora já actualizei o código e penso que esse bug está resolvido.
Quanto ao login ele é feito via AJAX e por isso não é mostrada nem a password nem o utilizador na URL, por outro lado, na página registo, os parâmetros são passados na URLce ai sim tens razão mas estou a tratar desse assunto, em breve estará disponível o registo via AJAX.

Abraço e obrigado por reportares esse BUG.

Apesar de ser por AJAX continua visível... não é na barra do URL, mas nas ligações que o teu computador faz.
Repara:

Screen Shot 2012-09-05 at 3.25.33 PM.png

Tas a ver as setinhas amarelas?
É a isso que o Mach4_PT se está a referir...
É facil ver que ligações e que outras pessoas dentro da tua rede, estão a fazer... Como tal também vejo as passwords delas.
Um pedido post não facilita tanto a coisa... (também é possivel de se ver... simplesmente não é tão fácil)
 
Back
Topo