Seguridad en aplicaciones Web

11,420 views
11,335 views

Published on

Diapositivas de la charla sobre seguridad en aplicaciones web.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
11,420
On SlideShare
0
From Embeds
0
Number of Embeds
440
Actions
Shares
0
Downloads
143
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Seguridad en aplicaciones Web

  1. 1. Seguridad web en aplicaciones Rails Ernesto Jiménez Caballero ernesto.jimenez@negonation.com
  2. 2. Sobre esta charla
  3. 3. ¿De qué vamos a hablar?
  4. 4. SQL Injections
  5. 5. SQL Injections class User < ActiveRecord::Base   def self.authenticate(login, password)     return User.find(:first, :conditions => quot;login = '#{login}' AND  crypted_password = '#{encrypt(password)}'quot;)   end end User.authenticate(quot;blabla' OR 'x' = 'x') OR ('x' = 'xquot;, 'lo_que_sea') # => SELECT * FROM users WHERE        (login = 'blabla' OR 'x' = 'x') OR       ('x' = 'x' AND crypted_password = '4123oijsjdir32josidjr032')       LIMIT 1; User.authenticate(quot;blabla' OR admin = 1) OR ('x' = 'xquot;, 'lo_que_sea') # => SELECT * FROM users WHERE       (login = 'blabla' OR admin = 1) OR       ('x' = 'x' AND crypted_password = '4123oijsjdir32josidjr032')       LIMIT 1;
  6. 6. SQL Injections class User < ActiveRecord::Base   def self.authenticate(login, password)     return User.find(:first, :conditions => [       quot;login = ? AND crypted_password = ?quot;,       login, encrypt(password)     ])   end end class User < ActiveRecord::Base   def self.authenticate(login, password)     return User.find(:first, :conditions => {       :login => login, :crypted_password => encrypt(password)     })   end end
  7. 7. :conditions => “x = #{x}” deja que Rails escape los parámetros de las consultas
  8. 8. Asignación masiva
  9. 9. Asignación masiva class UsersController < ApplicationController   def create     @user = User.create(params[:user])   end end <% 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 %>
  10. 10. Asignación masiva class UsersController < ApplicationController   def create     @user = User.create(params[:user])   end end
  11. 11. Asignación masiva class UsersController < ApplicationController   def create     @user = User.create(params[:user])   end end post :create, :user => {    :email => 'usuario@ejemplo.com',    :password => 'xxxx'} # => Usuario creado con los parámetros del formulario post :create, :user => {    :email => 'usuario@ejemplo.com',     :password => 'xxxx',    :admin => true} # => Escalada de privilegios!
  12. 12. Asignación masiva class User < ActiveRecord::Base   has_many :posts end class Post < ActiveRecord::Base   belongs_to :user end post :create, :user => {    :email => 'usuario@ejemplo.com',    :password => 'xxxx',    :post_ids => [1,2,3]} # => Se proclama autor de los posts 1, 2 y 3!
  13. 13. Asignación masiva class User < ActiveRecord::Base   attr_protected :admin end user = User.new(   :email => 'usuario@ejemplo.com',   :password => 'xxxx',   :admin => true) user.admin # => false user.attributes = {   :email => 'nuevo_email@ejemplo.com',   :admin => true } user.admin # => false user.admin = true user.admin # => true
  14. 14. Asignación masiva class User < ActiveRecord::Base   attr_accessible :email, :password end user = User.new(   :email => 'usuario@ejemplo.com',   :password => 'xxxx',   :admin => true) user.admin # => false user.attributes = {   :email => 'nuevo_email@ejemplo.com',   :admin => true } user.admin # => false user.admin = true user.admin # => true
  15. 15. attr_protected attr_accessible no introduzcas vulnerabilidades por olvidos
  16. 16. Cross Site Scripting
  17. 17. Cross Site Scripting <div class=quot;comentarioquot;>   <%= @comment.body %> </div> post :create, :comment => { :body => quot; <script>   /* Javascript malintencionado */ </script> quot; } # => <div class=quot;commentquot;>        <script>          /* Javascript malintencionado */        </script>      </div>
  18. 18. Cross Site Scripting <div class=quot;comentarioquot;>   <%= sanitize @comment.body %> </div> post :create, :comment => { :body => quot; <script>   /* Javascript malintencionado */ </script> quot; } # => <div class=quot;commentquot;>        &lt;script>          /* Javascript malintencionado */        &lt;/script>      </div>
  19. 19. Cross Site Scripting <div class=quot;comentarioquot;>   <%=h @comment.body %> </div> post :create, :comment => { :body => quot; <script>   /* Javascript malintencionado */ </script> quot; } # => <div class=quot;commentquot;>        &lt;script&gt;          /* Javascript malintencionado */        &lt;/script&gt;      </div>
  20. 20. sanitize Funciona con listas negras y no lo detecta todo
  21. 21. h bueeeeno, pero... ¿qué pasa si te olvidas uno? ¡¡¡es muy fácil olvidarse una letra!!!
  22. 22. sanitiza antes de guardar
  23. 23. Cross Site Request Forgery
  24. 24. Cross Site Request Forgery <img src=”http://web.com/nuevo_pass?pass=robado” />
  25. 25. Cross Site Request Forgery No es un problema en Rails 2.0
  26. 26. Accesos no autorizados
  27. 27. Accesos no autorizados class DraftsController < ApplicationController   def show     @draft = Draft.find(params[:id])   end   def destroy     @draft = Draft.destroy(params[:id])   end end # => Cualquier usuario puede ver y eliminar los borradores
  28. 28. Accesos no autorizados class DraftsController < ApplicationController   def show     @draft = current_user.drafts.find(params[:id])   end   def destroy     @draft = current_user.drafts.destroy(params[:id])   end end # => Solo el autor del borrador puede verlos y borrarlos
  29. 29. Acciones públicas
  30. 30. 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])   end end get :send_email,     :email => 'cualquiera@spam.es',     :body => 'Compra V14GR4! http://www.pastillitaazul.com' # => El código de send_mail se ejecuta aunque luego de error
  31. 31. 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])   end end
  32. 32. algunos consejos
  33. 33. jamás te fíes de lo que recibes en el servidor
  34. 34. ten cuidado con los datos que recibes, pero también con los que envías
  35. 35. controla las interfaces de tus cotroladores y modelos
  36. 36. no filtres con listas negras
  37. 37. no tengas miedo de escribir tests que prueben la seguridad   def test_should_avoid_xss_from_search_query     get :search, :q => '<script id=quot;injectionquot;>alert();</script>'     assert_no_tag :script, :attributes => {:id => 'injection' }   end
  38. 38. algunas herramientas
  39. 39. FireBug
  40. 40. Cookie Editor
  41. 41. Tamper Data
  42. 42. CURL
  43. 43. WWW::Mechanize
  44. 44. require 'rubygems' require 'mechanize' agent = WWW::Mechanize.new page = agent.get 'http://www.gmail.com' form = page.forms.first form.Email = '***your gmail account***' form.Passwd = '***your password***' page = agent.submit form page = agent.get page.search(quot;//metaquot;).first.attributes['href'].gsub(/'/,'') page = agent.get page.uri.to_s.sub(/?.*$/, quot;?ui=html&zy=nquot;) page.search(quot;//tr[@bgcolor='#ffffff']quot;)  do |row|   from, subject = *row.search(quot;//b/text()quot;)   url = page.uri.to_s.sub(/ui.*$/, row.search(quot;//aquot;).first.attributes[quot;hrefquot;])   puts quot;From: #{from}nSubject: #{subject}nLink: #{url}nnquot;   email = agent.get url   # .. end
  45. 45. ¿Preguntas?

×