Pergunta

Ao escrever o código, conscientemente programa defensivamente para garantir a alta qualidade do programa e para evitar a possibilidade de que seu código está sendo explorada de forma maliciosa, e.g.através de explorações de estouro de buffer ou a injeção de código ?

O que é o "mínimo" nível de qualidade que você sempre vai se aplicam ao seu código ?

Foi útil?

Solução

Na minha linha de trabalho, o nosso código tem que ser de qualidade superior.
Então, vamos nos concentrar em duas coisas principais:

  1. Teste
  2. As revisões de código

Os trazer para casa o dinheiro.

Outras dicas

Semelhante ao abyx, na equipe, eu sou os desenvolvedores de usar sempre os testes de unidade e de revisões de código.Além de que, eu também o objectivo de certificar-se de que eu não incorporar código que as pessoas pode use - costumo escrever código apenas para o conjunto básico de métodos necessários para o objeto na mão para funcionar como tem sido spec'd fora.Eu descobri que a incorporação de métodos que nunca pode ser usado, mas fornecem funcionalidade, inadvertidamente, pode introduzir um "backdoor" ou não intencional/imprevista e uso no sistema.

É muito mais fácil para voltar mais tarde e introduzir métodos, atributos e propriedades para as quais são convidados versus antecipando algo que pode nunca chegar.

Eu recomendo a ser defensiva para os dados que introduzir um "componente" ou enquadramento.Dentro de um "componente" ou quadro, deve-se pensar que os dados são "corretas".

Pensando assim.Ele é o autor da chamada para o fornecimento de parâmetros corretos em contrário, TODAS as funções e os métodos para verificar se todos incomming parâmetro.Mas se a seleção é feita somente para o autor da chamada a verificação é necessário somente uma vez.Assim, um parâmetro deve ser "correto" e, portanto, podem ser passadas através de níveis inferiores.

  1. Confira os dados a partir de fontes externas, usuários, etc
  2. Um "componente" ou quadro, deve-se sempre verificar incomming chamadas.

Se há um erro e um valor incorreto é usado em uma chamada.O que é realmente a coisa certa todo?Só tem uma indicação de que os "dados", o programa está trabalhando é errado e alguns, como AFIRMA, mas outros querem utilização avançada de relatórios de erros e a possível recuperação de erro.Em qualquer caso os dados é encontrado para ser defeituoso e, em alguns casos, é bom continuar a trabalhar nele.(observação é bom se servidores não morrer, pelo menos)

Uma imagem enviada a partir de um satélite pode ser um caso para tentar avançadas de recuperação de erro em...uma imagem baixados da internet para colocar um ícone de erro para...

Eu recomendo que as pessoas escrevem código que é fascista no ambiente de desenvolvimento e benevolente na produção.

Durante o desenvolvimento, você quer pegar ruim de dados/lógica/código o mais cedo possível para evitar problemas passa despercebido ou, resultando em problemas posteriores, onde a causa é difícil de controlar.

Na produção de lidar com problemas tão graciosamente quanto possível.Se algo é realmente um erro não recuperável, em seguida, processar e apresentar informações para o usuário.

Como um exemplo, aqui está o nosso código para Normalizar um vetor.Se você alimentá-lo ruim de dados em desenvolvimento, ele vai gritar, na produção, ele retorna um valor de segurança.

inline const Vector3 Normalize( Vector3arg vec )
{
    const float len = Length(vec);
    ASSERTMSG(len > 0.0f "Invalid Normalization");
    return len == 0.0f ? vec : vec / len;
}

Eu sempre trabalho para evitar coisas como ataques de injeção.No entanto, quando você trabalha em uma intranet interna do site, a maioria dos recursos de segurança, sinta-se como o esforço desperdiçado.Eu ainda fazê-las, talvez não tão bem.

Bem, existe um determinado conjunto de melhores práticas para a segurança.No mínimo, para aplicativos de banco de dados, você precisa prestar atenção para fora para a Injeção de SQL.

Outras coisas como o hash de senhas, criptografia de seqüências de caracteres de conexão, etc.são, também, um padrão.

A partir de agora, depende da aplicação real.

Felizmente, se você estiver trabalhando com estruturas como .Net, um monte de proteção de segurança vem incorporado.

Você tem sempre o programa defensivamente eu diria até mesmo para aplicativos internos, simplesmente porque os usuários podiam apenas por pura sorte escrever algo que divide seu aplicativo.Concedido, você provavelmente não tem que se preocupar em tentar enganá-lo sem dinheiro, mas ainda assim.Programe sempre na defensiva e assumir o aplicativo falhará.

Usando Test Driven Development certamente ajuda.Você escreve um único componente de cada vez e, em seguida, enumerar todos os casos potenciais factores de produção (através de testes antes de escrever o código.Isso garante que você cobriu todas as bases e não escrita qualquer legal código de que ninguém vai usar, mas pode quebrar.

Apesar de eu não fazer nada formal, eu geralmente gastam algum tempo procurando em cada classe e assegurando que:

  1. se eles estão em um estado válido que eles estejam em um estado válido
  2. não há nenhuma maneira de construí-los em um estado inválido
  3. Em circunstâncias excepcionais, eles vão falhar tão graciosamente quanto possível (freqüentemente esta é uma limpeza e jogar)

Isso depende.

Se estou realmente hackear alguma coisa para meu próprio uso, então vou escrever o melhor código que eu não tenho em que pensar.Permitir que o compilador ser meu amigo, avisos etc.mas eu não criar automaticamente tipos para o inferno do mesmo.

O mais provável é que o código está a ser utilizado, mesmo ocasionalmente, eu rampa até o nível dos controlos.

  • o mínimo de números mágicos
  • melhores nomes de variáveis
  • totalmente verificada & definido matriz/comprimentos de cadeia
  • programação por contrato afirmações
  • valor nulo verifica
  • exceções (consoante o contexto do código)
  • básico explicativo comentários
  • acessível a documentação de uso (se o perl etc.)

Vou dar uma definição diferente de programação defensivas, como a que é defendida por Eficaz Java por Josh Bloch.No livro, ele fala sobre como lidar com objetos mutáveis que os chamadores passar para o código (por exemplo, em setters), e objetos mutáveis que você passar para os chamadores (por exemplo, em getters).

  • Para setters, certifique-se de que para clonar qualquer objetos mutáveis, e armazenar o clone.Desta forma, os chamadores não pode alterar o passado no objeto depois que o fato de a quebra de seu programa de invariantes.
  • Para o empreendedor, quer voltar imutável vista de seus dados internos, se a interface permite que ele;ou então devolver um clone de dados interno.
  • Ao chamar fornecido pelo usuário retornos de chamada de dados internos, enviar uma imutável view ou clone, conforme apropriado, a menos que você queira o retorno de chamada para alterar os dados, caso em que você tem para validá-lo após o fato.

A mensagem é para se certificar de que não fora o código pode conter um alias para qualquer mutável objetos que você usa internamente, de modo que você pode manter seus invariantes.

Eu estou muito da opinião de que a programação correta irá proteger contra estes riscos.Coisas como evitando funções, que (no Microsoft C++ libraries pelo menos) são comumente preteridos devido a vulnerabilidades de segurança, e a validação de tudo o que cruza um limite externo.

Funções que só são chamadas a partir de seu código não deve exigir excessivo de validação de parâmetro porque você controle o chamador, que é, sem limite externo é atravessada.Funções de chamada por outras pessoas do código deve assumir que os parâmetros de entrada será inválido e/ou malicioso em algum ponto.

Minha abordagem para lidar com o exposto funções é simplesmente cair, com um útil mensagem, se possível.Se o chamador não pode obter os parâmetros para a direita, em seguida, o problema é no seu código e eles devem corrigir, não você.(Obviamente você forneceu a documentação para a sua função, desde que ele está exposto.)

A injeção de código é apenas um problema se o seu aplicativo é capaz de elevar o usuário atual.Se um processo pode injetar código em seu aplicativo, em seguida, ele poderia facilmente escrever o código para a memória e executá-lo de qualquer maneira.Sem ser capaz de obter acesso total ao sistema de injeção de código ataques são inúteis.(É por isso que as aplicações utilizadas pelos administradores não deve ser escrita pelo menor usuários.)

Na minha experiência, de forma positiva, empregando programação defensivas não significa necessariamente que você acaba melhorando a qualidade de seu código.Não me leve a mal, você precisa defensivamente programa para capturar os tipos de problemas que os usuários irão deparar - os usuários não gostam quando o seu programa falha em-los - mas isso é improvável, para tornar o código mais fácil de manter, testar, etc.

Vários anos atrás, fizemos de política para o uso das asserções em todos os níveis de nosso software e este, juntamente com testes de unidade, revisões de código, etc.além disso, o nosso aplicativo existente de conjuntos de teste - teve um significativo e positivo efeito sobre a qualidade do nosso código.

Java, Assinado Frascos e JAAS.

Java para evitar estouro de buffer e apontador/pilha batendo façanhas.

Não utilizar JNI.( Java Native Interface), ele expõe a DLL/bibliotecas Compartilhadas.

Assinado JAR para parar de classe do carregamento a ser um problema de segurança.

JAAS pode permitir que o aplicativo não confiar em ninguém, nem mesmo a si próprio.

J2EE tem (reconhecidamente limitado) suporte integrado para segurança baseada em Função.

Existe alguma sobrecarga para alguns, mas as falhas de segurança ir embora.

Resposta simples: Depende.Muito defensiva de codificação pode causar grandes problemas de desempenho.

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