Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Sunday, October 21, 2012

Security and Objects

Mobile code is one of the great challenges for software security. Lets say  you are writing an email application. The idea that people could send little apps to each other in email messages might seem like a potentially interesting feature: users could build polls, schedule meetings, play games, share interactive documents. Kind of cool.

And if the platform you are building upon supports reflectively evaluating code, it could be as easy as something like this (in OO pseudocode):

    define load_message(message)
        ...
        eval(message.code)

Of course it can't be that easy. What if the code in the message does something like:

    new stdlib.io.File("/").delete()

The standard way to avoid the vulnerability is to put the code in a so-called sandbox. It sounds very secure, but in practice this usually amounts to gathering up a list of "dangerous" call sites and inserting in each some code to check if the caller has permission to proceed. So the implementation of delete would include code along the lines of:

    define delete()
        if VM.callStackContainsEvilCode?()
            raise YouShallNotPassException()

        ...

This is fraught with problems. It requires runtime support for inspecting the call stack and a system for declaring that certain code has some level of authorization while some other code has a lower level. Not to mention the busywork of going trough the code and peppering that little snippet over every suspect call site. If you miss one — say, for instance, a method that gets the addresses of all contacts on your email application — and you have a security bug on your hands.

A better way ?

Perhaps there is a better way. Take another look at the offending line: new stdlib.io.File("/").delete(). It is only able to call the dangerous delete() method because it has a reference to a file object pointing to the root of the filesystem. And it only has that reference because it could reach for the File class on a global namespace. What if there was no global namespace?

It might seem weird, but it's not that hard to imagine a programming system lacking a global namespace. Many object-oriented languages, following Smalltalk's lead, have a notion of a metaclass, an object that represents a class. Many of them (also following Smalltak) also get by without a "new" operator. Objects are created by calling a method — usually named new() — on the metaclass object.

We are very close now. The last step, unfortunately not taken by most common languages, is to avoid anchoring the metaclass object onto a global namespace. The result is that code can only create objects of the classes it holds a reference to. And it only has a reference if it is given one via a method or constructor parameter.

Proceeding recursively, we end up with a stratified program. There is an entry point that receives a reference to the entire standard library, and each call site decides how much authority to grant each callee. On our example, when we evaluate external code we can grant very little authority, meaning we can pass the evaluated code just a handful of references. Care must be taken so that none of them will direct or indirectly provide a way to create a File. In a way, object design becomes security policy.

And we get very fine-grained control over such policy. We could, for instance, grant loaded code authority to write on a designated directory just by passing it a reference to the Directory object for that directory. Our choices get even more interesting when we realize we can pass references to proxies instead of real objects in order to attenuate authority. Continuing with our example, hoping it doesn't get too contrived, we could build a proxy for the Directory that checks if callers exceed a given quota of disk space.

Research

I have mentioned above that most common languages don't fit this post's description. But there are languages that do, a prime example is E. In fact, there is a whole area of research for dealing with security in this manner, it's called "object capability security".

I'm not really a security guy, I got interested in the area due to the implications for language and system design. If you got interested, for any reason, please check out Mark Miller's work. He is the creator of the E language and the javascript-based Caja project. His thesis is very readable.

Wednesday, July 05, 2006

963 páginas

Como estou sem criatividade para escrever alguma coisa original, vou tomar a tradicional solução bloggeira. Não, não vou postar fotos de animais de estimação, estou falando da outra solução bloggueira para preguiça intelectual: book reviews.

Admito que esse semestre foi bem fraco para leituras; só tive tempo para quatro livros:
  • "Bartleby, o Escriturário", do Melville, edição de bolso da L&PM. Não manjo de crítica litéraria e não sou presunçoso o suficiente para pensar que poderia análisar um clássico da literatura. Só digo que gostei muito, e recomendo. Ah, e ele é curto, assim como esse comentário.


  • "The Design of Everyday Things", do Donald Norman. Obrigatório para qualquer pessoa que esteja envolvida na criação de qualquer coisa, o livro fala da interação entre as pessoas e os objetos cotidianos (ou não tão cotidianos). Norman é um especialista em psicologia cognitiva que se interessou pelo estudo da usabilidade quando foi chamado a compor o conselho designado para apontar as falhas que levaram ao desastre de Three Mile Island. Ele descobriu que muito do que se costuma apontar como "falha humana" na verdade é causado por objetos que foram projetados sem levar em conta as pessoas que terão de operá-los. No caso da usina, encontrou problemas como séries de controles muito parecidos produzindo ações muito diferentes e alarmes que disparavam com tanta frequência que acabaram por ser ignorados no momento crítico. O livro discute esse exemplo e muitos outros, mas não é apenas um catálogo de erros de usabilidade. Ele também formula uma teoria de como as pessoas aprendem a usar as tais "everyday things" e apresenta uma série de conselhos para quem têm a responsabilidade de projetar seja uma usina nuclear, uma chaleira ou um software. Para instigar mais o apetite, são estes os conselhos: 1. Use both knowledge in the world and knowledge in the head; 2. Simplify the structure of tasks; 3. Make things visible: bridge the gulfs of execution and evaluation; 4. Get the mappings right; 5. Exploit the power of constraints, both natural and artificial; 6. Design for error; 7. When all else fails, standardize. Algum ponto negativo? Ficar folheando até o fim para ler as notas é um saco (e eu sou simplesmente incapaz de pular e deixar para depois...).

  • "Secrets & Lies", do Bruce Schneier. O autor é um criptógrafo notório, e um dos livros anteriores dele, o Applied Criptography, é a obra mais popular sobre o assunto. Aqui, ele trata de segurança digital de uma maneira ampla. O livro é muito bom, mas eu esperava algo diferente do que encontrei. Usando um termo encontrado repetidas vezes no texto, pode-se dizer que o livro não é destinado a security experts, nem a aspirantes à expert, mas sim à quem contrata os tais security experts. Isso não implica que a leitura seja inútil para quem tem perfil técnico, pois as idéias do Schneier sobre como abordar a segurança são sempre muito inteligentes e às vezes até um pouco surpreendentes. Uma destas é a a constatação de que a comunidade de segurança computacional põe ênfase exagerada em medidas preventivas, como se fosse possível se proteger de todo e qualquer ataque futuro, e negligencia as outras fases: detecção e resposta. Outra tese relacionada é resumida no mantra "segurança não é um produto, é um processo", que é uma daquelas coisas que parecem óbvias até que alguém nos chame a atenção para as ramificações. Enfim, não me arrependo de tê-lo lido e até recomendo, mas a falta de profundidade me incomoda. Especialmente quando percebo que o autor sabe tratar de assuntos complexos sem alienar o leitor leigo; prova disso é o primoroso capítulo 6, que explica em linhas gerais as principais técnicas criptográficas sem entrar em detalhes teóricos, mas conseguindo ilutrar bem a mecânica básica e a importância de cada ferramenta.
  • Little Schemer, da MIT Press. O comentário sobre esse fica para depois. Só adianto que é um ótimo livro mas não compre sem dar uma folheada antes...