45
Seguridad web en aplicaciones Rails Ernesto Jiménez Caballero [email protected]

Seguridad en aplicaciones Web

Embed Size (px)

DESCRIPTION

Diapositivas de la charla sobre seguridad en aplicaciones web.

Citation preview

Page 1: Seguridad en aplicaciones Web

Seguridad web en aplicaciones Rails

Ernesto Jiménez [email protected]

Page 2: Seguridad en aplicaciones Web

Sobre esta charla

Page 3: Seguridad en aplicaciones Web

¿De qué vamos a hablar?

Page 4: Seguridad en aplicaciones Web

SQL Injections

Page 5: Seguridad en aplicaciones Web

class User < ActiveRecord::Base  def self.authenticate(login, password)    return User.find(:first, :conditions => "login = '#{login}' AND crypted_password = '#{encrypt(password)}'")  endend

User.authenticate("blabla' OR 'x' = 'x') OR ('x' = 'x", 'lo_que_sea')# => SELECT * FROM users WHERE       (login = 'blabla' OR 'x' = 'x') OR      ('x' = 'x' AND crypted_password = '4123oijsjdir32josidjr032')      LIMIT 1;

User.authenticate("blabla' OR admin = 1) OR ('x' = 'x", 'lo_que_sea')# => SELECT * FROM users WHERE      (login = 'blabla' OR admin = 1) OR      ('x' = 'x' AND crypted_password = '4123oijsjdir32josidjr032')      LIMIT 1;

SQL Injections

Page 6: Seguridad en aplicaciones Web

SQL Injectionsclass User < ActiveRecord::Base  def self.authenticate(login, password)    return User.find(:first, :conditions => [      "login = ? AND crypted_password = ?",      login, encrypt(password)    ])  endend

class User < ActiveRecord::Base  def self.authenticate(login, password)    return User.find(:first, :conditions => {      :login => login, :crypted_password => encrypt(password)    })  endend

Page 7: Seguridad en aplicaciones Web

:conditions => “x = #{x}”deja que Rails escape los parámetros de las consultas

Page 8: Seguridad en aplicaciones Web

Asignación masiva

Page 9: Seguridad en aplicaciones Web

Asignación masivaclass UsersController < ApplicationController  def create    @user = User.create(params[:user])  endend

<% from_for :user, :url => users_path do |f| %>  <label>email:    <%= f.text_field :email %>  </label>  <label>password:    <%= f.text_field :password %>  </label>  <%= submit_tag 'Registrarse' %><% end %>

Page 10: Seguridad en aplicaciones Web

Asignación masivaclass UsersController < ApplicationController  def create    @user = User.create(params[:user])  endend

Page 11: Seguridad en aplicaciones Web

Asignación masivaclass UsersController < ApplicationController  def create    @user = User.create(params[:user])  endend

post :create, :user => {   :email => '[email protected]',   :password => 'xxxx'}# => Usuario creado con los parámetros del formulario

post :create, :user => {   :email => '[email protected]',    :password => 'xxxx',   :admin => true}# => Escalada de privilegios!

Page 12: Seguridad en aplicaciones Web

Asignación masivaclass User < ActiveRecord::Base  has_many :postsend

class Post < ActiveRecord::Base  belongs_to :userend

post :create, :user => {   :email => '[email protected]',   :password => 'xxxx',   :post_ids => [1,2,3]}# => Se proclama autor de los posts 1, 2 y 3!

Page 13: Seguridad en aplicaciones Web

Asignación masivaclass User < ActiveRecord::Base  attr_protected :adminend

user = User.new(  :email => '[email protected]',  :password => 'xxxx',  :admin => true)user.admin # => falseuser.attributes = {  :email => '[email protected]',  :admin => true }user.admin # => false

user.admin = trueuser.admin # => true

Page 14: Seguridad en aplicaciones Web

Asignación masivaclass User < ActiveRecord::Base  attr_accessible :email, :passwordend

user = User.new(  :email => '[email protected]',  :password => 'xxxx',  :admin => true)user.admin # => falseuser.attributes = {  :email => '[email protected]',  :admin => true }user.admin # => false

user.admin = trueuser.admin # => true

Page 15: Seguridad en aplicaciones Web

attr_protectedattr_accessible

no introduzcas vulnerabilidades por olvidos

Page 16: Seguridad en aplicaciones Web

Cross Site Scripting

Page 17: Seguridad en aplicaciones Web

Cross Site Scripting<div class="comentario">  <%= @comment.body %></div>

post :create, :comment => { :body => "<script>  /* Javascript malintencionado */</script>" }# => <div class="comment">       <script>         /* Javascript malintencionado */       </script>     </div>

Page 18: Seguridad en aplicaciones Web

Cross Site Scripting<div class="comentario">  <%= sanitize @comment.body %></div>

post :create, :comment => { :body => "<script>  /* Javascript malintencionado */</script>" }# => <div class="comment">       &lt;script>         /* Javascript malintencionado */       &lt;/script>     </div>

Page 19: Seguridad en aplicaciones Web

Cross Site Scripting<div class="comentario">  <%=h @comment.body %></div>

post :create, :comment => { :body => "<script>  /* Javascript malintencionado */</script>" }# => <div class="comment">       &lt;script&gt;         /* Javascript malintencionado */       &lt;/script&gt;     </div>

Page 20: Seguridad en aplicaciones Web

sanitizeFunciona con listas negras y no lo detecta todo

Page 21: Seguridad en aplicaciones Web

hbueeeeno, pero... ¿qué pasa si te olvidas uno?

¡¡¡es muy fácil olvidarse una letra!!!

Page 22: Seguridad en aplicaciones Web

sanitiza antes de guardar

Page 23: Seguridad en aplicaciones Web

Cross Site Request Forgery

Page 24: Seguridad en aplicaciones Web

Cross Site Request Forgery<img src=”http://web.com/nuevo_pass?pass=robado” />

Page 25: Seguridad en aplicaciones Web

Cross Site Request ForgeryNo es un problema en Rails 2.0

Page 26: Seguridad en aplicaciones Web

Accesos no autorizados

Page 27: Seguridad en aplicaciones Web

Accesos no autorizadosclass DraftsController < ApplicationController  def show    @draft = Draft.find(params[:id])  end

  def destroy    @draft = Draft.destroy(params[:id])  endend

# => Cualquier usuario puede ver y eliminar los borradores

Page 28: Seguridad en aplicaciones Web

Accesos no autorizadosclass DraftsController < ApplicationController  def show    @draft = current_user.drafts.find(params[:id])  end

  def destroy    @draft = current_user.drafts.destroy(params[:id])  endend

# => Solo el autor del borrador puede verlos y borrarlos

Page 29: Seguridad en aplicaciones Web

Acciones públicas

Page 30: Seguridad en aplicaciones Web

Acciones públicas# Ejemplo muy chorra :)class UsersController < ApplicationController  def invite    current_user.invitations.create(params[:email],)    send_email  end    def send_email    UserMailer.deliver_email(params[:email], params[:body])  endend

get :send_email,    :email => '[email protected]',    :body => 'Compra V14GR4! http://www.pastillitaazul.com'# => El código de send_mail se ejecuta aunque luego de error

Page 31: Seguridad en aplicaciones Web

Acciones públicas# Ejemplo muy chorra :)class UsersController < ApplicationController  def invite    current_user.invitations.create(params[:email],)    send_email  end  protected  def send_email    UserMailer.deliver_email(params[:email], params[:body])  endend

Page 32: Seguridad en aplicaciones Web

algunos consejos

Page 33: Seguridad en aplicaciones Web

jamás te fíes de lo que recibes en el servidor

Page 34: Seguridad en aplicaciones Web

ten cuidado con los datos que recibes, pero también con los

que envías

Page 35: Seguridad en aplicaciones Web

controla las interfaces de tus cotroladores y

modelos

Page 36: Seguridad en aplicaciones Web

no filtres con listas negras

Page 37: Seguridad en aplicaciones Web

no tengas miedo de escribir tests que prueben la seguridad

  def test_should_avoid_xss_from_search_query    get :search, :q => '<script id="injection">alert();</script>'    assert_no_tag :script, :attributes => {:id => 'injection' }  end

Page 38: Seguridad en aplicaciones Web

algunas herramientas

Page 39: Seguridad en aplicaciones Web

FireBug

Page 40: Seguridad en aplicaciones Web

Cookie Editor

Page 41: Seguridad en aplicaciones Web

Tamper Data

Page 42: Seguridad en aplicaciones Web

CURL

Page 43: Seguridad en aplicaciones Web

WWW::Mechanize

Page 44: Seguridad en aplicaciones Web

require 'rubygems'require 'mechanize'

agent = WWW::Mechanize.new

page = agent.get 'http://www.gmail.com'form = page.forms.firstform.Email = '***your gmail account***'form.Passwd = '***your password***'page = agent.submit form

page = agent.get page.search("//meta").first.attributes['href'].gsub(/'/,'')page = agent.get page.uri.to_s.sub(/\?.*$/, "?ui=html&zy=n")page.search("//tr[@bgcolor='#ffffff']")  do |row|  from, subject = *row.search("//b/text()")  url = page.uri.to_s.sub(/ui.*$/, row.search("//a").first.attributes["href"])  puts "From: #{from}\nSubject: #{subject}\nLink: #{url}\n\n"

  email = agent.get url  # ..end

Page 45: Seguridad en aplicaciones Web

¿Preguntas?