nunojob:~ dscape/08$ echo The Black Sheep

Archive for the ‘Software’ Category

myAmbrosio

Para aqueles que andam sempre atentos as novas startups aqui está mais um projecto inovador acabadinho de sair da Universidade do Minho. Apesar de o projecto ainda estar muito verde os autores já contam com algumas parcerias importantes, assim como o sempre necessário apoio financeiro.

A ideia por trás do Ambrosio é um agregador de produtos/lojas de comercio tradicional, servindo este como veiculo de promoção das lojas/produtos e fornecendo aos utilizadores finais produtos que, por exemplo, não conseguem comprar num Hipermercado perto de si. Outro tipo de mercado que se pode abrir é certamento o do turismo rural através de, por exemplo, uma sugestão de onde dormir, onde comer ou indicação de onde estão a decorrer as festas tradicionais da terra.

Caso estejam interessados no conceito podem ver o video explicativo acabadinho de sair e contactar os autores com sugestões.

Advertisements

Summer School CDDIP 2008, Struer, Denmark – Selected!

I was selected for all paid trip Struer (Denmark) representing University of Minho – Portugal in the Summer School CDDIP 2008 Erasmus IP program. As far as I know at least five lucky Portuguese students will attend.

But what is CDDIP? CDDIP stands for Conceptual Design and Development of Innovative Products and the goal is to facilitate better interdisciplinary and multidisciplinary collaboration for BSc and MSc students with different technical backgrounds.

If you are from another country and you are also going you can leave me a comment. See you there!

Devolvam as passwords aos vossos utilizadores com Ruby on Rails 2.0

Uma coisa que me chateia imenso nas webapplications de trazer por casa – traduzindo aquelas que são feitas por colegas meus ou por outros amadores pela web fora – é o facto de guardarem quase sempre as passwords na base de dados em plaintext. Acho que não tem o direito de saber a password que uso, nem que a use exclusivamente nesse site (como é o caso)

Assim, se quem fez a aplicação for mal intencionado, pode simplesmente obter a vossa password escrevendo

select * from users where user.username = 'nick'

Mas mesmo que não sejam mal intencionados, outra pessoa pode aceder a base de dados. Ou podem simplesmente não se ter protegido contra sql injection. Há um milhão de razões pelas quais nunca se deve guardar as password em plaintext, sendo que a principal deles é o facto da password não ser vossa. É do utilizador. E isso faz toda a diferença! Não acreditam em mim certo? Estou a exagerar.

Convido-os a visitar esta página

Agora procurem por ‘qualquer_coisa. O resultado é

  • Pesquisa por “\’qualquer_coisa”:

Este \’ é importantíssimo pois significa que a página se esta a proteger contra ataques de sql injection. Caso contrario um hacker podia, com alguma sorte, obter informação privilegiada que estava contida nessa base de dados.

Mas ninguém faz um erro destes, certo? Errado. Vamos ao google e procurem php em páginas de Portugal. O sexto resultado, e único que testei, é a associação nacional de farmácias. Se procurarem por ‘qualquer_coisa o resultado é um não tão surpreendente erro. Isto é um exemplo de milhares, alguns dos quais onde vocês inserem as vossa password (e sabe-se lá o que mais) diariamente. Não se sentiam melhor se soubessem que nessa base de dados não está a vossa password?

Mas voltando ao assunto, a táctica que vou usar consiste em usar um algoritmo de one way hash chamado SHA. O utilizador, quando se regista no site, insere a sua password. Esta é processada (num processo que se chama de digest) para uma hash que contém não a password mas sim a encriptação dessa password em SHA. Como SHA é um algoritmo de one-way-hash, é fácil obter a hash única para qualquer palavra mas quase impossível de decifrar no sentido inverso. Para ser suficiente, mas não é.

Comecemos por ir para a consola do rails. Entrem no terminal e naveguem até onde tem a vossa Ruby on Rails web application. Agora escrevam.

./script/console

Quando lá estiverem podem verificar que aplicando este algoritmo a palavra porto obtemos sempre a mesma resposta.

>> password = 'porto'
=> "porto"
>> Digest::SHA256.hexdigest(password)
=> "01735c5ff1608734e4c38449a00b74bb9a8d5423ed548238da70178e9e803483"
>> Digest::SHA256.hexdigest(password)
=> "01735c5ff1608734e4c38449a00b74bb9a8d5423ed548238da70178e9e803483"

Não sei se repararam mas o nosso utilizador usa uma palavra pass muito fraca. Isto vai fazer a diferença, por o hacker pode obter a password facilmente se tiver a hash.

Como? Sim eu disse que era muito difícil crackar o SHA, alias não conheço ninguém que o tenha feito. Ninguém conhece :P

Mas o hacker pode pegar numa lista de palavras comuns nas passwords e, para cada uma das palavras associar a hash correspondente. Agora se tiver a vossa hash pode comparar com o dicionário que criou descobrir algumas das passwords da base de dados, aquelas que estavam na lista de palavras comuns.

Para resolver este problema usamos um salt. Um salt é também uma palavra (como a vossa password) que sera usada para evitar esta técnica. é mais simples mostrar que explicar, e por isso mesmo:

>> password = 'porto'
salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
>> salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
=> "19L6gVcD"
>> salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
=> "CqEVe632"
>> password = 'porto'
=> "porto"
>> Digest::SHA256.hexdigest(password + salt)
=> "c017e1c49096149097050c76f0406dce9245058e0d..."

De certeza que o hacker não vai procurar pela string portoCqEVe632 e, portanto, os nossos utilizadores estão seguros. Caso queiram saber um pouco mais sobre o que se passa no criação do salt, e que é aquele pack(‘m’) peçam nos comentários e eu escrevo um artigo sobre isso. Senão nunca mais saio daqui! :P.

Agora surge a pergunta, como usar esta informação em rails. Simples.

Vamos começar por criar um projecto:

rails secureusers && cd secureusers

Agora precisamos de criar o modelo de utilizador

./script/generate model User username:string \
  password_hash:string password_salt:string
rake db:migrate

Abram o vosso User.rb model, apaguem o que lá tem, e insiram o seguinte código

require 'digest/sha2'
class User < ActiveRecord::Base
# usei o attr_accessible em vez do
# attr_protected :password_hash, :password_salt
# porque é boa prática em Rails usar o enabled para 
# os campos acessíveis e não o contrário.
#
# Imaginem que tinham um campo isAdmin e se 
# esqueciam de por no protected.
# Ao dizerem que enabled só o :username impedem 
# o acesso a todo e qualquer outro campo,
# excepto aqueles que foram explicitamente 
# escolhidos por vocês.
  attr_accessible :username
  attr_accessor :password

  def before_save
    unless password.blank?
      salt = &#91;Array.new(6){rand(256).chr}.join&#93;.pack("m").chomp
      self.password_salt, self.password_hash = salt,
      Digest::SHA256.hexdigest(password + salt)
    end
  end

  def self.authenticate(username, password)
    user = User.find :first,
        :conditions => ['username = ?', username])
      if user.blank?
        raise "O utilizador não existe"
      elsif Digest::SHA256.hexdigest(password + user.password_salt) != user.password_hash
        raise "A autenticação falhou"
      else
        user
      end
  end
end

Usei o attr_accessible em vez do protected porque considero esta uma boa practica. Prefiro dizer quais os campos acessíveis que quais os que se deve proteger. Assim não corro o risco de me esquecer de proteger algum campo. E os que são para ver nota-se bem quando faltam :P Podem ler mais sobre isto aqui.

Depois de toda esta explicação o código deve ser muito facil de entender. Até para quem não sabe Ruby. Vamos testar?

>> nuno = User.new
=> #<user id: nil,
  username: nil,
  password_hash: nil,
  password_salt: nil,
  created_at: nil,
  updated_at: nil>
>> nuno.username = 'nuno'
=> "nuno"
>> nuno.password = 'porto'
=> "porto"
>> nuno.save
=> true
>> nuno
=> #</user><user id: 1, 
  username: "nuno",
  password_hash: "c490ea11d96be24ece2ca0dba11d84fc9b...",
  password_salt: "V+b7Sqjh",
  created_at: "2008-02-12 19:28:54",
  updated_at: "2008-02-12 19:28:54">

E agora autenticar:

User.authenticate 'nuno', 'porto'
=> #</user><user id: 1, 
  username: "nuno",
  password_hash: "c490ea11d96be24ece2ca0dba11d84fc9b...",
  password_salt: "V+b7Sqjh",
  created_at: "2008-02-12 19:28:54",
  updated_at: "2008-02-12 19:28:54">

Fixe. É so por no session[:user] ;) Para finalizar aconselho-vos vivamente a suportarem open-id para o processo de autenticação dos utilizadores. Existem plugins muito bons que o fazem, e podem ler mais sobre open-id no seu fantástico guia supersónico.

Working different models in the same form on Ruby on Rails

Well it’s been a heck of a week, loving somethings on rails and hating others :P

Anyway I had a problem with working with different models on a form. If you are having the same kind of issues I’ll give you some pointers:

My notes file is so big I think I’ll never solve all those issues. *g* Anyway another pointer I can give you is to check out haml. I didn’t used it but it sure is simpler than html.

Skitch Invites (Mac OS X only)

I have been receiving some emails asking me how do I create these images. Well I use Skitch, which is one of my favorite Mac OS X apps (along with Books, Textmate and iSync). Unfortunately it’s still invite only.

Anyway if your interested in giving Skitch a try just leave a comment in this post, and I’ll send it to the email you provided as soon as possible.

Screencast app for Mac OS X Leopard

I’m looking for the best screencast software (sound recording is a must have) to run on my MacBook.

So far I found the following software:

From what I have read so far it seems iShowU gathers most of the preferences. But when a app is prefixed by an i mac users seem to love it immediately.

Anyone tried any of these products? What are your thoughts on them? Which one would you advice me to use?

[EDIT: Currently I have tested most of these products and I’m using iShowU and KeyCastr]

MacBook OS X Leopard Tips: Controlling the fan speed with Fan Control

I use my computer for something like 6 hours a day so it’s bound to get hot. I didn’t like the apple scheme for the fans that consists basically in making no noise until it’s hot and then make a lot of it.

So I looked for a open-source application to help me control the fan rpm and found Fan Control. I wouldn’t even post this if not for one simple fact: The source is included in the dmg file. Good job guys!