Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Criando aplicações web mais seguras

Nando Vieira
September 23, 2015

Criando aplicações web mais seguras

Manter sua aplicação segura é tão importante quanto o desenvolvimento em si. Infelizmente nem todo desenvolvedor faz a sua parte para garantir que os riscos de ataques foram minimizados. Nessa palestra você verá os problemas mais comuns, entenderá porque é importante manter seu aplicativo atualizado e conhecerá algumas boas práticas para minimizar as chances de ser hackeado.

Palestra apresentada na Web.br 2015.

Nando Vieira

September 23, 2015
Tweet

More Decks by Nando Vieira

Other Decks in Technology

Transcript

  1. @fnando
    CRIANDO
    APLICAÇÕES WEB
    MAIS SEGURAS

    View full-size slide

  2. 75% DOS ATAQUES
    ACONTECEM NA WEB
    A web é um ambiente realmente assustador.
    http://fnando.me/1c6

    View full-size slide

  3. USE UM FRAMEWORK WEB
    ESTABELECIDO
    Frameworks web possuem diversas
    configurações de segurança por padrão.

    View full-size slide

  4. BRECHAS DE SEGURANÇA
    EXISTEM
    Frameworks podem conter falhas de
    segurança desconhecidas.

    View full-size slide

  5. DEVS INTRODUZEM FALHAS
    DE SEGURANÇA
    Também temos responsabilidade pelo código
    que escrevemos.

    View full-size slide

  6. NANDO VIEIRA

    View full-size slide

  7. OWASP
    Open Web Application Security Project
    https://www.owasp.org

    View full-size slide

  8. A1 – Injeção de código
    A2 – Quebra de autenticação e Gerenciamento de Sessão
    A3 – Cross-Site Scripting (XSS)
    A4 – Referência Insegura e Direta a Objetos
    A5 – Configuração Incorreta de Segurança
    A6 – Exposição de Dados Sensíveis
    A7 – Ausência de Controle de Acesso
    A8 – Cross-Site Request Forgery (CSRF)
    A9 – Utilização de Componentes com Vulnerabilidades Conhecidas
    A10 – Redirecionamentos Não Validados
    OWASP — TOP 10 2013
    http://fnando.me/1c9

    View full-size slide

  9. INTRODUÇÃO DESTES
    CONCEITOS
    Como esses vetores de ataque funcionam e
    como se previnir.

    View full-size slide

  10. A10
    REDIRECIONAMENTOS
    NÃO VALIDADOS
    http://fnando.me/1ca

    View full-size slide

  11. /dashboard login?return=/dashboard
    /dashboard

    View full-size slide

  12. VALIDE OS HOSTS
    PERMITIDOS
    Ou simplesmente ignore-os.

    View full-size slide

  13. require 'uri'
    class ReturnUrl
    def self.url(default_url, return_url)
    uri = URI.parse(return_url)
    return default_url if return_url.blank?
    return default_url unless Config.redirect_allowed_hosts.include?(uri.host)
    return_url
    rescue URI::InvalidURIError
    default_url
    end
    end

    View full-size slide

  14. class SessionsController < ApplicationController
    def create
    if Authenticator.call(params[:credential], params[:password], session)
    redirect_to RedirectUrl.url(dashboard_path, params[:return_to])
    else
    render :new
    end
    end
    end

    View full-size slide

  15. class SessionsController < ApplicationController
    def create
    if Authenticator.call(params[:credential], params[:password], session)
    redirect_to RedirectUrl.url(dashboard_path, params[:return_to])
    else
    render :new
    end
    end
    end

    View full-size slide

  16. A9
    UTILIZAÇÃO DE
    COMPONENTES COM
    VULNERABILIDADES
    CONHECIDAS
    http://fnando.me/1cb

    View full-size slide

  17. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160

    View full-size slide

  18. http://xkcd.com/1354

    View full-size slide

  19. http://xkcd.com/1354

    View full-size slide

  20. http://xkcd.com/1354

    View full-size slide

  21. http://xkcd.com/1354

    View full-size slide

  22. http://xkcd.com/1354

    View full-size slide

  23. http://xkcd.com/1354

    View full-size slide

  24. Received heartbeat response:
    0000: 02 40 00 D8 03 00 53 43 5B 90 9D 9B 72 0B BC 0C [email protected][...r...
    0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90 .+..H...9.......
    00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 2F 33 34 2E ....#......./34.
    00e0: 30 2E 31 38 34 37 2E 31 33 37 20 53 61 66 61 72 0.1847.137 Safar
    00f0: 69 2F 35 33 37 2E 33 36 0D 0A 52 65 66 65 72 65 i/537.36..Refere
    0100: 72 3A 20 68 74 74 70 73 3A 2F 2F 77 77 77 2E 74 r: https://examp
    0110: 72 61 79 2E 63 6F 6D 2E 62 72 2F 0D 0A 41 63 63 le.org/......Acc
    0120: 65 70 74 2D 45 6E 63 6F 64 69 6E 67 3A 20 67 7A ept-Encoding: gz
    0130: 69 70 2C 64 65 66 6C 61 74 65 2C 73 64 63 68 0D ip,deflate,sdch.
    0140: 0A 41 63 63 65 70 74 2D 4C 61 6E 67 75 61 67 65 .Accept-Language
    0150: 3A 20 70 74 2D 42 52 2C 70 74 3B 71 3D 30 2E 38 : pt-BR,pt;q=0.8
    0160: 2C 65 6E 2D 55 53 3B 71 3D 30 2E 36 2C 65 6E 3B ,en-US;q=0.6,en;
    0170: 71 3D 30 2E 34 0D 0A 43 6F 6F 6B 69 65 3A 20 5F q=0.4..Cookie: _
    0180: 5F 75 74 6D 61 3D 34 37 35 37 33 32 31 38 2E 31 _utma=47573218.1
    0190: 33 31 31 35 32 35 38 34 37 2E 31 34 30 30 30 39 311525847.140009
    01a0: 31 35 31 39 2E 31 34 30 30 30 39 36 38 36 35 2E 1519.1400096865.
    01b0: 31 34 30 30 31 35 31 35 33 34 2E 33 3B 20 5F 5F 1400151534.3; __
    01c0: 75 74 6D 7A 3D 34 37 35 37 33 32 31 38 2E 31 34 utmz=47573218.14
    01d0: 30 30 30 39 31 35 31 39 2E 31 2E 31 2E 75 74 6D 00091519.1.1.utm
    01e0: 63 73 72 3D 28 64 69 72 65 63 74 29 7C 75 74 6D csr=(direct)|utm
    01f0: 63 63 6E 3D 28 64 69 72 65 63 74 29 7C 75 74 6D ccn=(direct)|utm
    0200: 63 6D 64 3D 28 6E 6F 6E 65 29 0D 0A 0D 0A 25 30 cmd=(none)....%0

    View full-size slide

  25. Received heartbeat response:
    0000: 02 40 00 D8 03 00 53 43 5B 90 9D 9B 72 0B BC 0C [email protected][...r...
    0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90 .+..H...9.......
    00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 2F 33 34 2E ....#......./34.
    00e0: 30 2E 31 38 34 37 2E 31 33 37 20 53 61 66 61 72 0.1847.137 Safar
    00f0: 69 2F 35 33 37 2E 33 36 0D 0A 52 65 66 65 72 65 i/537.36..Refere
    0100: 72 3A 20 68 74 74 70 73 3A 2F 2F 77 77 77 2E 74 r: https://examp
    0110: 72 61 79 2E 63 6F 6D 2E 62 72 2F 0D 0A 41 63 63 le.org/......Acc
    0120: 65 70 74 2D 45 6E 63 6F 64 69 6E 67 3A 20 67 7A ept-Encoding: gz
    0130: 69 70 2C 64 65 66 6C 61 74 65 2C 73 64 63 68 0D ip,deflate,sdch.
    0140: 0A 41 63 63 65 70 74 2D 4C 61 6E 67 75 61 67 65 .Accept-Language
    0150: 3A 20 70 74 2D 42 52 2C 70 74 3B 71 3D 30 2E 38 : pt-BR,pt;q=0.8
    0160: 2C 65 6E 2D 55 53 3B 71 3D 30 2E 36 2C 65 6E 3B ,en-US;q=0.6,en;
    0170: 71 3D 30 2E 34 0D 0A 43 6F 6F 6B 69 65 3A 20 5F q=0.4..Cookie: _
    0180: 5F 75 74 6D 61 3D 34 37 35 37 33 32 31 38 2E 31 _utma=47573218.1
    0190: 33 31 31 35 32 35 38 34 37 2E 31 34 30 30 30 39 311525847.140009
    01a0: 31 35 31 39 2E 31 34 30 30 30 39 36 38 36 35 2E 1519.1400096865.
    01b0: 31 34 30 30 31 35 31 35 33 34 2E 33 3B 20 5F 5F 1400151534.3; __
    01c0: 75 74 6D 7A 3D 34 37 35 37 33 32 31 38 2E 31 34 utmz=47573218.14
    01d0: 30 30 30 39 31 35 31 39 2E 31 2E 31 2E 75 74 6D 00091519.1.1.utm
    01e0: 63 73 72 3D 28 64 69 72 65 63 74 29 7C 75 74 6D csr=(direct)|utm
    01f0: 63 63 6E 3D 28 64 69 72 65 63 74 29 7C 75 74 6D ccn=(direct)|utm
    0200: 63 6D 64 3D 28 6E 6F 6E 65 29 0D 0A 0D 0A 25 30 cmd=(none)....%0

    View full-size slide

  26. ATUALIZE TÃO RÁPIDO
    QUANTO POSSÍVEL
    Não demore para corrigir falhas que são
    potencialmente destrutivas.

    View full-size slide

  27. ATUALIZE O SOFTWARE
    QUE VOCÊ USA
    Esta deve ser uma tarefa constante de seu
    projeto.

    View full-size slide

  28. A8
    CROSS-SITE
    REQUEST
    FORGERY
    http://fnando.me/1cc

    View full-size slide

  29. Envia formulário Transfere $$$

    View full-size slide




  30. Conta de destino



    Quantia




    View full-size slide

  31. USE NON-GET PARA AÇÕES
    QUE MUDAM O ESTADO
    Nunca utilize GET para ações que causam
    efeito colateral.

    View full-size slide


  32. Link inofensivo

    View full-size slide

  33. USE TOKEN DE SEGURANÇA
    NO FORMULÁRIO
    Rejeite qualquer alteração que não tiver um
    token válido.

    View full-size slide

  34. A7
    AUSÊNCIA DE
    CONTROLE DE
    ACESSO
    http://fnando.me/1cd

    View full-size slide

  35. AUTENTICAÇÃO
    Validar se você é quem você diz ser.
    AUTORIZAÇÃO
    Validar o que você pode fazer baseado em quem você é.

    View full-size slide

  36. VALIDE O NÍVEL DE
    PERMISSÃO
    Garanta que somente quem permissão pode
    acessar páginas restritas.

    View full-size slide

  37. class AdminPolicy < PermissionPolicy
    ALLOWED_EMAIL = /\A[^@]+@example\.com\z/
    def permit?(user)
    user && user.email.match(ALLOWED_EMAIL)
    end
    end
    AdminPolicy.permit?(current_user)

    View full-size slide

  38. class AdminController < ActionController::Base
    protect_from_forgery with: :exception
    before_action :authorize
    private
    def authorize
    return if authorized?
    reset_session
    redirect_to login_path
    end
    def authorized?
    AdminPolicy.permit?(current_user)
    end
    end

    View full-size slide

  39. A6
    EXPOSIÇÃO DE
    DADOS SENSÍVEIS
    http://fnando.me/1ce

    View full-size slide

  40. EXCLUA DADOS SENSÍVEIS
    DE SEUS LOGS
    Senhas, números de cartão de crédito, chaves
    de API, e tudo mais que for dado sensível.

    View full-size slide

  41. Rails.application.config.filter_parameters += [
    :password,
    :api_key,
    :credit_card_number,
    :credit_card_cvv
    ]

    View full-size slide

  42. CRIPTOGRAFE DADOS
    SENSÍVEIS
    Garanta que os dados são criptografados no
    nível da aplicação.

    View full-size slide

  43. USE UM ALGORITMO
    APROPRIADO PARA SENHAS
    Não utilize algoritmos de hashing como MD5,
    SHA1 e semelhantes.

    View full-size slide

  44. require 'bcrypt'
    password_digest = BCrypt::Password.create('your password', cost: 13)
    #=> $2a$13$uao9THAp2WaLxRyu3ZC7uuD92pPEMFXEukVwv8fZt//O.ugsue23O
    BCrypt::Password.new(password_digest) == 'your password'
    #=> true
    BCrypt::Password.new(password_digest) == 'invalid password'
    #=> false

    View full-size slide

  45. require 'benchmark'
    require 'benchmark/ips'
    require 'bcrypt'
    require 'digest/sha1'
    require 'digest/sha2'
    include BCrypt
    include Digest
    GC.disable
    PASSWORD = 'abcdefghij'
    DIGEST = Password.create(PASSWORD, cost: 13)
    SHA1_DIGEST = Digest::SHA1.hexdigest(PASSWORD)
    SHA256_DIGEST = Digest::SHA256.hexdigest(PASSWORD)
    SHA512_DIGEST = Digest::SHA512.hexdigest(PASSWORD)
    Benchmark.ips do |x|
    x.report('sha1') { SHA1.hexdigest(PASSWORD) == SHA1_DIGEST }
    x.report('sha256') { SHA256.hexdigest(PASSWORD) == SHA256_DIGEST }
    x.report('sha512') { SHA512.hexdigest(PASSWORD) == SHA512_DIGEST }
    x.report('bcrypt') { Password.new(DIGEST) == PASSWORD }
    x.compare!
    end

    View full-size slide

  46. Calculating -------------------------------------
    sha1 28.511k i/100ms
    sha256 27.043k i/100ms
    sha512 24.511k i/100ms
    bcrypt 1.000 i/100ms
    -------------------------------------------------
    sha1 437.174k (±14.5%) i/s - 2.138M
    sha256 308.032k (±12.2%) i/s - 1.541M
    sha512 228.471k (±15.0%) i/s - 1.128M
    bcrypt 1.609 (± 0.0%) i/s - 9.000 in 5.603296s
    Comparison:
    sha1: 437174.0 i/s
    sha256: 308032.1 i/s - 1.42x slower
    sha512: 228471.5 i/s - 1.91x slower
    bcrypt: 1.6 i/s - 271735.68x slower

    View full-size slide

  47. Calculating -------------------------------------
    sha1 28.511k i/100ms
    sha256 27.043k i/100ms
    sha512 24.511k i/100ms
    bcrypt 1.000 i/100ms
    -------------------------------------------------
    sha1 437.174k (±14.5%) i/s - 2.138M
    sha256 308.032k (±12.2%) i/s - 1.541M
    sha512 228.471k (±15.0%) i/s - 1.128M
    bcrypt 1.609 (± 0.0%) i/s - 9.000 in 5.603296s
    Comparison:
    sha1: 437174.0 i/s
    sha256: 308032.1 i/s - 1.42x slower
    sha512: 228471.5 i/s - 1.91x slower
    bcrypt: 1.6 i/s - 271735.68x slower

    View full-size slide

  48. SALVAR HASHES SEM SALT
    NÃO AJUDA MUITO
    Rainbow tables possuem muitas senhas e a
    probabilidade de você encontrar senhas
    comuns ali é alta.

    View full-size slide

  49. A5
    CONFIGURAÇÃO
    INCORRETA DE
    SEGURANÇA
    http://fnando.me/1cf

    View full-size slide

  50. EM PRODUÇÃO USE O
    AMBIENTE DE PRODUÇÃO
    Certifique-se que definiu as variáveis de
    ambiente RAILS_ENV e RACK_ENV.

    View full-size slide

  51. PROTEJA PAINÉIS DE
    ADMINISTRAÇÃO
    Garanta que todos os painéis exigem
    autenticação e autorização.

    View full-size slide

  52. CONTRATE UM SYS ADMIN
    COMPETENTE
    Administrar um servidor corretamente é
    muito mais difícil do apenas fazer sua
    aplicação executar.

    View full-size slide

  53. A4
    REFERÊNCIA INSEGURA
    E DIRETA A OBJETOS
    http://fnando.me/1cg

    View full-size slide

  54. UTILIZE IDENTIFICADORES
    NÃO SEQUENCIAIS
    Identificadores sequenciais são fáceis de
    modificar.

    View full-size slide

  55. #BREAKING: Twitter $TWTR Q1
    Revenue misses estimates, $436M
    vs. $456.52M expected
    Selerity
    @selerity
    https://twitter.com/Selerity/status/593129551221432320

    View full-size slide

  56. CREATE TABLE proposals (
    id uuid primary key not null default uuid_generate_v4(),
    title text not null
    )

    View full-size slide

  57. create_table :proposals, id: :uuid do |t|
    t.text :title, null: false
    end

    View full-size slide

  58. VALIDE A PERMISSÃO DE
    USUÁRIOS
    Garanta que o usuário pode acessar apenas o
    que ele deve.

    View full-size slide

  59. class ProposalsController < ApplicationController
    def edit
    @proposal = Proposal.find(params[:id])
    end
    end

    View full-size slide

  60. class ProposalsController < ApplicationController
    def edit
    @proposal = current_user.proposals.find(params[:id])
    end
    end

    View full-size slide

  61. class ProposalsController < ApplicationController
    def edit
    @proposal = current_user.proposals.find(params[:id])
    end
    end

    View full-size slide

  62. A3
    CROSS-SITE
    SCRIPTING
    http://fnando.me/1ch

    View full-size slide

  63. INJEÇÃO DE JAVASCRIPT
    NO CONTEXTO DA PÁGINA
    Isto permite roubo de cookies, redirecionamento
    para outros sites, exibição de ads, defacement,
    executar ações no lugar do usuário.

    View full-size slide

  64. USE TEMPLATE ENGINE COM
    AUTOESCAPING
    E evite desabilitar o escapamento de HTML de sua
    template engine.

    View full-size slide

  65. FAÇA O ESCAPAMENTO DO
    CONTEÚDO NO JAVASCRIPT
    Se o dado veio do usuário, então não renderize-o
    como HTML.

    View full-size slide

  66. $.getJSON("/info", function(profile){
    $(".profile").html(profile.bio);
    });
    $.getJSON("/info", function(profile){
    $(".profile").text(profile.bio);
    });

    View full-size slide

  67. $.getJSON("/info", function(profile){
    $(".profile").html(profile.bio);
    });
    $.getJSON("/info", function(profile){
    $(".profile").text(profile.bio);
    });

    View full-size slide

  68. $.getJSON("/info", function(profile){
    $(".profile").html(profile.bio);
    });
    $.getJSON("/info", function(profile){
    $(".profile").text(profile.bio);
    });

    View full-size slide

  69. USE CONTENT SECURITY
    POLICY
    Reduz riscos de XSS ao declarar quais recursos
    podem ser carregados.

    View full-size slide

  70. http://content-security-policy.com/

    View full-size slide

  71. USE OUTROS HEADERS DE
    SEGURANÇA
    Isso ajuda previnir outros tipos de ataque, como
    defacement através de injeção de iframes.

    View full-size slide

  72. X-Frame-Options: DENY
    Bloqueia a renderização de frames, iframes e .
    X-XSS-Protection: 1; mode=block
    Ativa filtros extras de prevenção contra XSS.
    X-Content-Type-Options: nosniff
    Rejeita arquivos que não possuem MIME type correto.

    View full-size slide

  73. MARQUE COOKIES COMO
    HTTP ONLY
    Não deixe cookies que só serão usados pelo
    servidor serem modificados pelo navegador.

    View full-size slide

  74. NUNCA CONFIE EM DADOS
    ENVIADOS PELO USUÁRIO
    Se veio do usuário, então o dado é inseguro.

    View full-size slide

  75. A2
    QUEBRA DE
    AUTENTICAÇÃO E
    GERENCIAMENTO DE
    SESSÃO
    http://fnando.me/1ci

    View full-size slide

  76. GARANTA QUE A SESSÃO
    USE SSL
    Se a página identifica usuários logados, deve
    necessariamente usar SSL.

    View full-size slide

  77. MARQUE OS COOKIES COMO
    HTTP ONLY E SEGUROS
    Isso dificulta o roubo de identidades através de
    falhas como XSS.

    View full-size slide

  78. Rails.application.config.session_store :cookie_store, {
    :key => "_example_session",
    :httponly => true,
    :secure => Config.force_ssl?,
    :expire_after => 1.hour
    }
    Rails.application.configure do
    config.force_ssl = Config.force_ssl?
    end
    config/environments/production.rb
    config/initializers/session_store.rb

    View full-size slide

  79. UTILIZE OUTRO TIPO DE
    STORAGE DE SESSÃO
    Usar cookies é prático, mas pode introduzir falhas
    de segurança.

    View full-size slide

  80. config/initializers/session_store.rb
    Rails.application.config.session_store :redis_session_store, {
    key: '_myapp-session',
    secure: Config.force_ssl?,
    redis: {
    expire_after: 1.hour,
    key_prefix: 'myapp:session:',
    url: Config.session_redis_url
    }
    }
    https://github.com/roidrage/redis-session-store

    View full-size slide

  81. DEFINA A EXPIRAÇÃO DA
    SESSÃO POR INATIVIDADE
    Isso pode diminuir o engajamento de usuários em
    sites de redes sociais.

    View full-size slide

  82. ADICIONE AUTENTICAÇÃO
    DE DOIS FATORES
    Dê incentivos para que os usuários ativem esse
    fator extra de autenticação.

    View full-size slide

  83. https://twofactorauth.org

    View full-size slide

  84. A1
    INJEÇÃO DE
    CÓDIGO
    http://fnando.me/1cj

    View full-size slide

  85. NUNCA CONFIE EM DADOS
    ENVIADOS PELO USUÁRIO
    Se veio do usuário, então o dado é inseguro.

    View full-size slide

  86. params[:name] = 'Basecamp'
    Project.where("name = '#{params[:name]}'")
    #=> SELECT "projects".* FROM "projects" WHERE (name = 'Basecamp')

    View full-size slide

  87. params[:name] = "' OR 1=1) --"
    Project.where("name = '#{params[:name]}'")
    #=> SELECT "projects".* FROM "projects" WHERE (name = '' OR 1=1) --')

    View full-size slide

  88. NUNCA INTERPOLE
    QUERIES SQL
    E se realmente decidir fazer isso, faça o
    escapamento dos parâmetros.

    View full-size slide

  89. params[:name] = ActiveRecord::Base.sanitize("' OR 1=1) --")
    Project.where("name = #{params[:name]}")
    #=> SELECT "projects".* FROM "projects" WHERE (name = ''' OR 1=1) --')

    View full-size slide

  90. ActiveRecord::Base#average
    ActiveRecord::Base#count
    ActiveRecord::Base#maximum
    ActiveRecord::Base#minimum
    ActiveRecord::Base#sum
    ActiveRecord::Base.exists?
    ActiveRecord::Base.having
    ActiveRecord::Base.joins
    ActiveRecord::Base.lock
    ActiveRecord::Base.order
    ActiveRecord::Base.pluck
    ActiveRecord::Base.reorder
    ActiveRecord::Base.select
    http://rails-sqli.org

    View full-size slide

  91. NUNCA CONFIE EM DADOS
    ENVIADOS PELO USUÁRIO
    Se veio do usuário, então o dado é inseguro.

    View full-size slide

  92. AINDA É CEDO, PODE
    RESUMIR PARA MIM?
    tl;dw

    View full-size slide

  93. A WEB É UM LUGAR
    EXTREMAMENTE HOSTIL
    1.
    Sempre assuma que sua aplicação pode sofrer
    ataques a qualquer instante.

    View full-size slide

  94. ACOMPANHE SITES DE
    SEGURANÇA
    2.
    E garanta que o software que você é atualizado
    frequentemente.

    View full-size slide

  95. A SUA CREDIBILIDADE
    ESTÁ EM JOGO
    3.
    Não arrisque algo que sua empresa demorou para
    conquistar.

    View full-size slide

  96. @fnando
    OBRIGADO.

    View full-size slide