Pergunta

eu correr em um pouco de um problema com um Regex Eu estou usando para nomes de seres humanos.

$rexName = '/^[a-z' -]$/i';

Suponha que um usuário com o nome de Jürgen deseja registrar? Ou Bob? Isso é muito comum na Europa. Existe uma notação especial para isso?

EDIT :, jogou apenas o nome Jürgen contra um criador regex, e divide a palavra-se na letra u ...

http://www.txt2re.com/ index.php3? s = J% FCrgen + Blalock & submit = Mostrar + Jogos

EDIT2:? Allright, desde a verificação de tais coisas específicas é difícil, por que não usar um regex que simplesmente verifica se há caracteres ilegais

$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";

(agora quais destes podem realmente ser usado em qualquer atentado Hacker?)

Por exemplo. Isso permite 'e - sinais, mas você precisa de um; para fazê-lo funcionar em SQL, e esses serão stopped.Any outros personagens que são comumente usados ??para injeção HTML de ataques de SQL que eu estou perdendo?

Foi útil?

Solução

Eu realmente dizer: não tente nomes Validate: um dia ou outro, seu código vai encontrar um nome que ele pensa que é "errado" ... E como você acha que um iria reagir quando um aplicativo lhe diz " seu nome não é válido "?

Dependendo do que você realmente deseja alcançar, você pode considerar o uso de algum tipo de lista negra / filtros, para excluir os "não-nomes" que você pensou sobre: ??será talvez deixar alguns "maus-nomes" passe, mas, ao menos, não deve impedir qualquer nome existente de acessar a sua aplicação.

Aqui estão alguns exemplos de regras que vêm à mente:

  • nenhum número
  • nenhum caráter especial, como "~{()}@^$%?;:/*§£ø e provavelmente alguns outros
  • não mais que 3 espaços?
  • nenhum dos "admin", "apoio", "moderador", "teste", e algumas outras não-nomes óbvios que as pessoas tendem a usar quando não deseja digitar seu nome real ...
    • (mas, se eles não querem dar-lhe seu nome, a sua ainda não vai, mesmo se você proibi-los de digitar algumas letras aleatórias, eles poderiam simplesmente usar um nome real ... O que não é deles)

Sim, esta não é perfeito; e sim, ele vai deixar alguns não-nomes passar ... Mas é provavelmente muito melhor para sua aplicação do que dizer a alguém "seu nome está errado" (sim, eu insisto ^^)


E, para responder a um comentário que deixou sob uma outra resposta:

Eu poderia simplesmente proibir a maioria comando caracteres para injeção SQL e XSS ataques,

Sobre SQL Injection, você deve escapar de seus dados antes de enviar aqueles à base de dados; e, se você sempre escapar esses dados (! você deve), você não precisa se preocupar com o que os usuários podem entrada ou não:. como ele escapou, sempre, não há risco para você

Mesmo sobre XSS: como você sempre escapar de seus dados quando ouputting-lo (! Você deve), não há risco de injecção; -)


EDIT: se você só usar esse regex assim, ele não vai funcionar muito bem:

O código a seguir:

$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
if (preg_match($rexSafety, 'martin')) {
    var_dump('bad name');
} else {
    var_dump('ok');
}

Será que você obtenha, pelo menos, um aviso:

Warning: preg_match() [function.preg-match]: Unknown modifier '{'

Você deve escapar, pelo menos, alguns desses caracteres especiais; Eu vou deixar você cavar Padrões PCRE para mais informações (há é realmente um monte de saber sobre PCRE / regex; e eu não vou ser capaz de explicar tudo)

Se você realmente quiser verificar que nenhum desses personagens está dentro de uma determinada peça de dados, você pode acabar com algo assim:

$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'martin')) {
    var_dump('bad name');
} else {
    var_dump('ok');
}

(Esta é uma proposta rápida e suja, que tem de ser refinado!)

Este diz "OK" (bem, eu definitivamente espero que o meu próprio nome é ok!)
E o mesmo exemplo com alguns especiais caracteres, como este:

$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'ma{rtin')) {
    var_dump('bad name');
} else {
    var_dump('ok');
}

Será que dizer "mau nome"

Mas, por favor, note que eu tenho não totalmente testado isso, e provavelmente precisa de mais trabalho! Não use este em seu site a menos que você testou-o com muito cuidado!


Também nota que uma única citação pode ser útil quando se tenta fazer uma injeção SQL ... Mas é provavelmente um personagem que é legal em alguns nomes ... Assim, apenas excluindo alguns caracteres pode não ser suficiente; -)

Outras dicas

implementação PCRE do PHP suportes propriedades de caracteres Unicode que abrangem um conjunto maior de caracteres. Então, você poderia usar uma combinação de \p{L} (caracteres carta), \p{P} (caracteres de pontuação) e \p{Zs} (caracteres espaço separador):

/^[\p{L}\p{P}\p{Zs}]+$/

Mas pode haver caracteres que não são abrangidos por estas categorias de caracteres, enquanto pode haver alguma incluído que você não quer ser permitido.

Então, eu conselho você contra o uso de expressões regulares em um dado com uma vaga gama de valores como o nome de uma pessoa real tal.


Editar Como você editou sua pergunta e agora ver que você só quer evitar certos ataques de injeção de código:. Você deve melhor escapar esses personagens, em vez de rejeitá-los como uma potencial tentativa de ataque

Use mysql_real_escape_string ou instruções preparadas para consultas SQL, htmlspecialchars para a saída de HTML e outras funções apropriadas para outros idiomas.

Isso é um problema sem solução geral fácil. A coisa é que você realmente não pode prever quais caracteres um nome poderia conter. Provavelmente, a melhor solução é definir uma máscara de caráter negativo para excluir alguns caracteres especiais que você realmente não quer acabar em um nome.

Você pode fazer isso usando:

$ regexp = "/ ^ [ ^ ] + $ /

Se você está tentando analisar distante um nome humano em PHP, eu recomment Keith Beckman roteiro nameparse.php .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top