Fixe Práticas Do Coding

Este artigo delves nos aspectos mais técnicos da segurança no código usado executar uma aplicação, e fornece guidelines para desenvolver um processo do enforcement para a execução segura. O potencial para vulnerabilities em uma aplicação é reduzido por um projeto forte, mas pela execução dos selos da aplicação seu fate. O trabalho duro derramou em um projeto seguro torna-se inconsequential se a execução fosse feita mal. É também importante compreender que o inclusion de tecnologias ou de métodos de projeto segurança-relacionados necessariamente não implica nem não garante nenhum nível da segurança dentro de uma aplicação. A execução de uma aplicação e de toda a tecnologia de segurança usadas é um dos componentes finais que traz um nível elevado da confiabilidade.

A análise na fase da execução é a responsabilidade de colaboradores e de gerentes do desenvolvimento. Os colaboradores são responsáveis para executar o projeto bem, visto que os gerentes são responsáveis para determinar o processo que assegura uma execução boa. Isto pode ser feito através dos procedimentos estandardizados que incluem revisões documentadas do desenvolvimento e dos padrões, do projeto e de código do coding, e do treinamento do colaborador no que diz respeito à segurança no desenvolvimento da aplicação. Estes procedimentos beneficiam os colaboradores e as aplicações não obstante que as línguas são usadas ou o tipo de aplicação é desenvolvido.

As línguas o mais geralmente usadas são hoje a língua de programação de C, o Java, e as línguas scripting tais como o Perl e os escudos de UNIX. Cada um destes línguas e ambientes pode ser usado impropriamente comprometer a segurança de uma aplicação e do sistema em que funciona. Entretanto, este artigo não é uma lista de verificação para que os colaboradores sigam. Instead, o desenvolvimento de um processo segurança-focalizado do pensamento permite uma prática arguably mais forte do coding.

Pitfalls pelo C

As línguas de programação de C, que incluem C, C++, e objeto-C, são as línguas o mais geralmente usadas e podem ser perigosas nas mãos unsure. Fornecem o colaborador com a abilidade de manipular e alcançar muitas peças do sistema, tais como a memória, de limas e de dispositivos. Esta é uma força grande das línguas de C, mas o perigo levanta-se quando o colaborador faz erros. C fornece um nível elevado do acesso ao sistema operando-se subjacente, e há poucos verificações e contrapesos para proteger o colaborador. Se o colaborador escrever equivocadamente dados à posição errada do dispositivo ou de memória, o programa de C fará o que quer que o colaborador escreve, não obstante os dados ou o destino.

  

A primeira área vulnerável associada frequentemente com o C é o excesso do amortecedor. O seguinte código da amostra demonstra um excesso muito básico:

char string[10 ];
strcpy(string, "AAAAAAAAAAAAAAA");  / * 15 
"caráteres de A" 

Aqui, 15 "caráteres de A" são copí na área de memória para uma corda variável, que seja para sido uma disposição 10-character de estática. A função do strcpy() faz exatamente como dirigido com nenhuma consideração para o tamanho dos dados que estão sendo copí ou da posição a que vai. Um excesso do amortecedor ocorre quando o 11o elemento é copí na posição de memória, imediatamente depois da posição do 10o elemento da corda variável. Aplique agora este princípio a todos os dados de entrada que vierem de uma fonte externa, substituindo a corda de caráteres de "A". Isto permite que os atacantes controlem os efeitos do excesso.

A função do strcpy() é uma de diversas funções em C que não executam nenhuns limites que verificam e não permitem que os amortecedores arbitrariamente feitos sob medida sejam copí. Outras funções a evitar são gets(), strcat(), sprintf(), e a família do scanf() das funções. Há umas versões updated de algumas destas funções que reservam os comprimentos copí para ser especificado. Estes são strncpy(), strncat(), snprintf(), e fgets(). Estes modificaram funções copíam somente até o número dos caráteres especificados pelo parâmetro do comprimento. Em a maioria, os caráteres do comprimento são copí da fonte no destino:

strncpy(destination, fonte, comprimento);

Ponta

Ao usar as versões de "n" do strncpy() das funções da manipulação—de corda, o strncat(), o snprintf(), e o fgets()—sejam certos que o comprimento não é maior do que a corda do destino, melhor que a corda da fonte. O amortecedor pode overrun se o valor do comprimento for maior do que o tamanho do amortecedor do destino.

Ao usar ponteiros aos amortecedores, em vez dos amortecedores estaticamente declarados, você necessita alocar bastante memória para armazenar os valores que estão sendo copí. Use as funções da manipulação da memória, que permitem que você especifique o comprimento.

Ponta

Ao alocar a memória para dados da corda, não se esqueça de adicionar 1 ao comprimento total, a fim acomodar para o caráter terminando NULO. Sem um terminal NULO, os dados na memória diretamente depois que o último caráter da corda pôde ser considerado parte da corda.

Estas funções não são os únicos lugares onde os excessos do amortecedor ocorrem. Seja certo certificar-se de que a informação leia, copí, ou escrito a toda a posição de memória ou atribuído a uma variável caiba, ou que o destino alocado tem bastante espaço de armazenamento.

Ponta

Para evitar excessos do amortecedor em seu código, seja certo validar a entrada. Verifique o tamanho dos dados e da posição do armazenamento e use as funções da manipulação que geram quantidades de informação colaborador-especificadas em vez arbitrariamente por muito tempo dos pedaços dos dados.

As condições da raça adicionam um nível da complexidade a usar o código de C. As condições da raça podem ser exploradas em dois aspectos de arranjar em seqüência e de proteção—da criação do código de C.

Arranjar em seqüência consulta à ordem em que os eventos ocorrem em uma aplicação. As condições da raça podem resultar de arranjar em seqüência variações entre eventos dependentes, quando nenhum verificar é feito entre os eventos. Isto significa frequentemente um shortcoming em todas as rotinas error-checking e do validation usadas. Se duas funções funcionarem normalmente sequencialmente e a segunda função supuser que os resultados do primeiros são válidos, então a possibilidade para uma condição da raça existe. Os privilégios elevated são frequentemente alvos do ataque. A organização, combinada com arranjar em seqüência e verificar de erro, minimiza a possibilidade para condições da raça.

Esta é uma execução má que críe uma condição da raça:

increase_privs();
...
valor = special_app_function(); / * requer *
dos privilégios/
other_unreleted_function(); / * não requer 
* dos privilégios/
other_unreleated_function2(); / * ditto */
special_dependent_function(value); / * 
requer * dos privilégios/
...
exit();

Aqui, um par de práticas inseguras ocorre. Os privilégios da aplicação elevated cedo na aplicação, mas não são usados até mais tarde. São abandonados também nunca, assim a maioria de funcionalidade executam com níveis elevado-do que-higher-than-needed do privilégio. Finalmente, a condição da raça é criada com a organização que pobre—as funções dependentes não ocorrem perto de se. Um exemplo que resolva estes problemas é

increase_privs();
valor = special_app_function; / * requer * dos 
privilégios/
se (!validate_function(value)/* assegure a 
segurança do * do valor/
{
    do_error_processing(value); / * faça algo 
inteligente com * do erro/
}
special_dependent_function(value); / * 
requer * dos privilégios/
decrease_privs(); / * nenhum * mais longo 
dos privilégios da necessidade/
 
other_unreleted_function(); / * não requer 
* dos privilégios/
other_unreleated_function2(); / * ditto */

Anote as rotinas especiais do validation e processar de erro que são usadas antes de passar o valor a uma outra função.

Ponta

Organize a funcionalidade e combine-a com o validation para assegurar-se de que a informação prevista não esteja comprometida entre eventos dependentes.

Muitas condições da raça existem como o resultado do uso pobre da lima provisória. Quando estas limas são criadas, devem ser protegidas de encontro ao ataque externo durante a operação. UNIX e Windows permitem que o colaborador ajuste os bocados da permissão e as bandeiras operacionais ao criar uma lima. Permissões se disallow o acesso a qualquer um mas o proprietário do processo. Ao criar a lima usando a chamada do open(), ajuste as bandeiras de O_EXCL e de O_CREAT, que fazem com que a função retorne um erro se a lima que você está tentando criar já existir. Porque é uma lima provisória, não deve existir antes da necessidade para ele. Se a lima existir, este é um sinal possível do ataque. Ao usar estes métodos, é também importante verificar os valores do retorno das funções e limpá-los acima de todas as limas no evento de condições de erro. O seguinte exemplo mostra a sintaxe para abrir uma lima—ou para criar um, se não existir já—com permissões que permitem que somente o criador leia, escreva-o, e execute- que usa o macro da modalidade de S_IRWXU.

open("filename", O_CREAT | O_EXCL | O_WRONLY, S_IRWXU);

A chamada falhará caso a lima existir já por causa da bandeira de O_EXCL. Também, anote o nome de arquivo do unsecure. A convenção nomeando de estática usada aumenta o risco do ataque dramàtica porque um componente do ataque é fornecido já.

devido à presença aumentada de condições da raça da lima provisória e dos insecurities associados, diversos sistemas operando-se têm as funções específicas para criar limas provisórias em uma maneira segura.

Os colaboradores podem também usar potencialidades lima-travando internas de sistema operando-se controlar o acesso às limas. Estes métodos controlam o acesso nos componentes fundamentais da semente.

Ponta

Ao usar limas provisórias, randomize os nomes de arquivo, ajuste permissões fortes, e organize a criação, o uso, e a remoção das limas minimizar a possibilidade de ataque.

Um outro componente que aumente a confiabilidade e possa influenciar a segurança de uma aplicação é o valor do retorno. Quando pôde parecer óbvio, é importante forçar a necessidade de validar os valores do retorno das funções. As funções executam frequentemente em série e confiam nos resultados ou nos dados de uma função precedente. Verificando o valor do retorno de funções precedentes, a função dependente é protegida de executar com dados inválidos. Mesmo quando os eventos não são ataques, recuperar das circunstâncias anômalas aumenta o robustness da aplicação.

Este exemplo demonstra uma execução pobre que não verifique os valores do retorno:

n = do_string_check (corda, valid_characters); / * a
função retorna * interno/
se (== GOOD_RETURN de n)
{
    process_string(string);
}

Aqui, a execução é fraca porque o caso negativo, um retorno mau, é segurado nunca. Uma execução melhor é

n = do_string_check(string, valid_characters); 
/ * a função retorna * interno/
se (n! = GOOD_RETURN)
{
    special_error_processing_routine(n); / * o 
valor mau, faz algo */
}
process_string(string);

O retorno negativo é segurado pela rotina processando do-ERRO, que pode retirar o programa, pedir uma corda nova, ou converter o valor do retorno em um parâmetro válido. Se o valor do retorno for bom, vai à rotina process.

Ponta

A criação de rotinas reusáveis do evento e do erro fornece um mecanismo padrão por que todas as aplicações reagem aos vários ataques e edições. As idéias para estas rotinas incluem métodos comuns do validation para a corda e valores, funções do envoltório para executar verificações da integridade, e os mecanismos numéricos da proteção que validam variáveis e posições de memória. Sempre verifique e processe o valor do retorno de uma função.

 

O bocado seguinte do detalhe envolve o uso da informação sensível dentro da aplicação, including senhas, encryption, ou toda a outra informação confidencial. Como mencionado previamente, toda a informação do programa existe nas áreas do pool comum da memória que pode ser sujeito à leitura e à modificação por procedimentos externos. É benéfico cancelar a memória quando a informação é não mais longa no uso, a fim evitar de revelar a informação durante um ataque. O método o mais comum e o mais suficiente aos dados desobstruídos, este é consultado tipicamente a como zerando para fora da memória. Quando a informação armazenada é uma needed não mais longo, as posições do armazenamento devem overwritten com zero ou dados aleatórios para impedir que um atacante recupere a informação através dos dumps da memória ou de núcleo. Este procedimento torna-se particularmente importante quando o encryption está no uso. As chaves usaram-se cifrar e as mensagens do decrypt são as partes as mais importantes de um sistema cryptographic, e de tudo possível protegê-los necessidades ser feito.

Estes guidelines exemplify algumas das edições comuns que se levantam em aplicações C-baseadas. C é um muito popular e a língua poderosa que permite fornece a flexibilidade grande ao colaborador, e o cuidado deve ser feita exame com seu uso.

Um Perl de uma aplicação

O Perl é uma besta interessante que combine muitos dos benefícios de uma língua de programação estruturada, como C, com a flexibilidade e a integração de um escudo de UNIX. O Perl permite que o colaborador críe procedimentos ou sub-rotinas, defina variáveis, e utilize as aplicações e os comandos disponíveis com o sistema operando-se. Estas potencialidades, e sua força com expressões e analisar gramaticalmente regulares, Perl da elasticidade uma presença forte em aplicações da correia fotorreceptora, administração do sistema, e automatização.

Os programas do Perl não são geralmente suscetíveis aos excessos do amortecedor por causa da natureza fraca datilografada de suas variáveis e declarações. Ao contrário de C, wherein as variáveis e a memória necessitam ser definidas como uma classe particular do armazenamento e a memória deve ser alocada para elas, o Perl faz tudo automaticamente e trata tudo como dados da corda. Faça exame do seguinte exemplo:

#!/path/to/perl
$one = 1;
$one_s = "1";  # nenhum diferente do que 
$one
$two = $one + #; # o 
resultado é 2, ou "2", que são equivalentes

Em C, o $one variável seria declarado provavelmente um inteiro e #, uma corda. A adição dos dois elementos resultaria também em um valor errôneo. O Perl não se diferencia entre os tipos diferentes, assim que $two é atribuído 2, ou "2"—são equivalentes no Perl. A língua também não cai rapina às exigências do alocamento de memória que outras línguas exibem. O seguinte exemplo é completamente aceitável no Perl:

#!/path/to/perl
$var1 = "AAAAA";
$var2 = "BBBB";
$var2 = #; # $var2 transforma-se 
"AAAAA";

$var2 faz exame no valor novo de cinco "caráteres de A". Todas as variáveis são alocadas dinâmicamente; não há nenhum conceito do espaço de armazenamento pré-ajustado que não poderia ser transbordado.

O Perl é suscetível, entretanto, às condições da raça e aos vulnerabilities associados com a execução de programas externos. O cuidado deve ser dado a arranjar em seqüência das funções. O validation da entrada é ingualmente importante no Perl, a fim impedir a exploração de aplicações externas.

O Perl suporta a potencialidade para abrir limas, similarmente a C e a outras línguas, conseqüentemente o uso de limas provisórias deve incorporar permissões apropriadas e bandeiras da criação.

O uso do Perl em programas Correia-baseados do cgi é também extremamente popular. Os riscos os mais grandes associaram com seu uso neste ambiente ocorrem durante o validation da entrada e a execução de programas de sistema externos de dentro. Para proteger a aplicação, diversas precauções podem ser feitas exame. Usar-se taint-verifica mecanismos do Perl, qualquer jogo variável fora do programa não será passado a todo o programa funcionado pela aplicação. Todas as variáveis ajustaram-se pela variável tainted tornam-se tainted. Taint-verifique a modalidade é particularmente útil para evitar vulnerabilities, wherein as variáveis unchecked do usuário são passadas surreptitiously aos programas chamados da aplicação do Perl. Para inicializar a versão 5 do Perl em taint-verifique a modalidade, usam o seguinte encabeçamento do certificado:

#!/path/to/perl –T # funcionam em 
taint-verificam a modalidade

A precaução seguinte deve analisar gramaticalmente valores da entrada para remover os meta-characters e os valores não desejados. Isto ajuda proteger de encontro aos ataques que exploram a parâmetro-passagem aos escudos e às outras aplicações. O seguinte exemplo mostra uma rotina simples que faça a varredura de uma corda da entrada para todos os meta-characters que possam ser interpretados por um programa:

$unclean_input = &get_HTML_forms_response();
if($unclean_input = ~  tr /;|`!$&*()[]{} :'"//)
{
    # cópia para fora de algum HTML que indica aqui 
a falha
    &do_some_error_reporting();
}

Neste caso, a rotina relata um erro se um meta-character for encontrado. Os métodos alternativos substituem meta-characters, ou continuam somente se nenhum meta-character for encontrado.

Uma precaução final é o uso de um escudo funcionar outras aplicações. Como com a chamada do system() de UNIX e a chamada do exec() de Windows, a chamada do system() no Perl permite que o colaborador funcione uma outra aplicação. A chamada do exec() no Perl funciona como essa chamada em UNIX que—o processo running é substituído pelo programa indicou. Estas funções podem ser particularmente perigosas quando usadas no os ambientes que permitem que o usuário input, como o cgi programam ou as utilidades de sistema. Se o validation da entrada não ocorrer, a aplicação pode ser explorada para executar os programas arbitrários que podem afetar o sistema. O seguinte exemplo demonstra os insecurities de usar o system() com nonvalidated a entrada. Suponha que o usuário forneceu o username;/bin/rm rf –da corda/que se tornou atribuído ao variável #:

system("ecommerce_app # ");

Isto traduz eficazmente ao username do ecommerce_app de /bin/sh; /bin/rm –rf/. supondo que o programa está funcionando com privilégios, o programa executará um escudo para funcionar a aplicação do e-comércio; bata o semicolon do escudo, que é o separador de comando em um escudo; e rm então funcionado –rf, que apaga o sistema de lima inteiro.

Milha Java Es Su Java

Java é uma invenção relativamente recente no mundo de computar distribuído do Internet. Traz ao fruition o conceito do código plataforma-independente. Java trabalha escrevendo o código e compilando o em um formato especial que seja funcionado então em máquinas virtuais de Java. A máquina virtual (VM) é específico da plataforma, mas o código que os funcionamentos nele não são. Java permite que os browsers da correia fotorreceptora e os sistemas remotos funcionem umas aplicações mais complexas e mais interativas. O web browser alcança um Web site e recebe um Java applet Do usuário. Este applet então funciona no web browser e pode comunicar-se com o web server originando. Quando introduzido, Java transformou Web pages de estática em aplicações dinâmicas e fluindo. Desde os dias adiantados, o uso de Java expandiu em muitas áreas de aplicação distribuídas diferentes tais como a gerência de rede, dispositivos encaixados do Internet, e outras funções de serviço público.

Java é um exemplo fino de uma língua cujos os colaboradores considerem a segurança nos estágios adiantados do projeto. As versões iniciais de Java tiveram uma arquitetura well-documented da segurança, chamada o sandbox, que impediu o Java applet ou a aplicação Dos recursos de sistema de acesso. Enquanto o uso de Java começou a expandir, a necessidade levantou-se para o acesso aos recursos de sistema fora do sandbox. A primeira versão do jogo do desenvolvimento de Java forneceu o uso de applet assinados. O modelo descreve um applet que seja assinado digital para verificar seu criador. Quando a assinatura digital é verificada, o applet está confiado então pelo sistema local, que permite o acesso do applet a outros recursos de sistema. Este método digital da assinatura envolve uma quantidade justa de complexo que programa para trabalhar corretamente. É também importante anotar que este modelo da segurança de um Java applet Digital assinado é danificado. Qualquer um pode assinar um applet. Um applet malicioso pode ser assinado pelo atacante e downloaded pelo web browser. O web browser verifica eficazmente que o applet malicioso está escrito certamente pelo atacante, e então executa-o feliz, a o que resultado é programado nele.

A iteração atual e segunda da arquitetura da segurança de Java é muito mais poderosa e flexível do que mais cedo versões. Isto permite que Java incorpore muitas áreas de desenvolvimento da aplicação previamente além de suas potencialidades. A arquitetura nova da segurança de Java usa fàcilmente as políticas da segurança e os métodos de controle definíveis do acesso que permitem que um applet ou uma aplicação alcancem recursos específicos aos graus variando. Com relação aos guidelines apresentou-se aqui, os desenhadores de Java analisaram as vários interações e vulnerabilities atuais com aplicações distribuídas do Internet, e chegaram em um modelo que fornecesse a segurança elevada com a flexibilidade extrema. Para a documentação completa em Java e em seu APIs, veja http://java.sun.com.

O jogo e o UNIX do escudo

UNIX descasca o formulário a base da interação do usuário com um sistema de UNIX. Os escudos são comando-linha intérpretes que suportam algum nível da automatização e da programação no formulário de certificados de escudo. Estes certificados são usados frequentemente automatizar tarefas do sistema, para executar operações repetitivas, e aplicações funcionadas da correia fotorreceptora do cgi. Como com Perl, as áreas de risco potencial são validation input, condições da raça, interação com limas externas e programas, e a organização da funcionalidade.

Em UNIX, as operações privilegiadas podem ser funcionadas por um usuário privilegiado, ou podem ser ajustadas ao funcionamento como um usuário privilegiado. Há umas diferenças subtle entre os dois métodos. Todas as limas em um sistema de UNIX, including aplicações, têm um jogo dos atributos que incluem o usuário e agrupam a posse, e um jogo de bandeiras das permissões. Combinada, permitem que o acesso da lima seja controlado estritamente. As aplicações normais são possuídas por um usuário e, dependendo das permissões de acesso, puderam ser funcionadas somente pelo proprietário, por um grupo, ou por qualquer um no sistema. As aplicações herdam os privilégios do usuário que os funciona. Uma aplicação que requeira privilégios da raiz pode ser funcionada por um usuário da non-raiz, mas, naqueles pontos onde uns privilégios mais elevados são requeridos, por ela falhará. Para superar este e permitir que os usuários normais alcancem determinadas funções privilegiadas, UNIX fornece as bandeiras de SetUID e de SetGID. Quando permitida, fazem com que a aplicação funcione como o proprietário ou o grupo para essa aplicação que—ajustaram o usuário ID (UID) da aplicação a whomever a possui.

Muito os programas do cgi e de sistema requerem o acesso aos recursos de sistema e são raiz de SetUID. Isto aplica-se aos programas compilados, tais como programas de C, e aos certificados, including o Perl e os escudos de UNIX. Os usuários e os colaboradores experientes de UNIX advertem frequentemente sobre os perigos dos certificados de escudo de SetUID que fornecem privilégios da raiz. Como discutidos mais cedo, o validation e as condições input da raça são explorados fàcilmente quando o certificado não é protegido corretamente. Ao funcionar um certificado como um usuário privilegiado, não há nenhuma maneira mais fácil entregar sobre as chaves ao castelo do que um certificado de escudo fraco. Tais certificados são particularmente perigosos quando programados sem medidas de segurança porque um escudo é interativo pela natureza. A entrada da fonte dos usuários, e o escudo executam uma função. O Perl tem muitos verificações internas e contrapesos que permitem um uso mais seguro de SetUID.

Dispositivos Do Internet

Os dispositivos do Internet são aqueles sistemas e dispositivos cuja a finalidade inteira é computar do Internet. Todos os guidelines do projeto, considerações da língua de programação, vulnerabilities, e paradigms se operando são diretamente relevantes aos dispositivos do Internet. Os dispositivos do Internet usam frequentemente sistemas operando-se, aplicações, e métodos comuns realizar seus objetivos. Se a aplicação no desenvolvimento seguir este trajeto, atenção especial do pagamento a toda a informação apresentada aqui. Alguns dispositivos do Internet são desenvolvidos do risco, incorporando somente projetos e tecnologias recentemente desenvolvidos. Avaliar o risco da segurança para estes sistemas requer o diligence extra. É especial importante integrar a segurança em um processo do projeto ao partir do risco.

este é um artigo adicionado por Tamas Querolin


Disclaimer: Nosso Web site não é responsável para a informação contida por este artigo. Este artigo em nenhuma maneira reflete as vistas, as opiniões, os pensamentos ou a opinião da equipe de funcionários do diretório dos artigos.

Observação da tradução: O artigo "práticas seguras do coding" foi traduzido usando um serviço de tradução automatizado. Nós desculpamo-nos sincerely por todos os erros da tradução que ocorram. Obrigado compreendendo.

Online: 611 users browsing the articles directory