03 juillet 2014

NFC, le retour

Après diverses recherches, j'approfondis la question du paiement sans contact et de la sécurisation associée.



Je me base entre autre sur cet article qui explique en détail les différentes sécurités utilisées sur une carte bancaire.

Donc la bande magnétique d'une CB comporte vos infos bancaires, plus un code de contrôle qui est le résultat d'un DES(numéro, expiration, code service, clé secrète banque).

Ce code est lu par tout les lecteurs de piste CB, et peut être rejoué tel quel - sécurité 0 contre la copie, mais aujourd'hui les paiements sur le Net ne sont plus possible sans le code de contrôle visuel.

Le "code de contrôle visuel" est issu du même principe avec un code de service différent. Il permet de vérifier que vous êtes bien en possession de la carte bleue. Il n'est pas en relief et est (sauf chez Amex) imprimé au dos, donc relativement à l'abris. Si vous êtes parano vous pouvez le gratter, comme ça pas de risque en cas de vol.

La puce NFC utilise un code généré dynamiquement (dCVV) ce qui évite de rejouer le même échange NFC comme on pourrait copier une piste magnétique. Ce code n'est donc pas identique à celui qu'on trouve sur la piste magnétique, et ne permet pas de reconstituer une fausse carte bleue sans effort.

Sauf que ... la compatibilité ascendante est nécessaire au niveau des terminaux de paiement, aussi vous pouvez utiliser les données issue d'un échange NFC pour forger une piste magnétique valide (voir cet article - le lien vers la replay demonstration est malheureusement mort). La sécurité est alors basée sur le bon comportement du terminal de paiement (y compris l'appli reliée au dongle Square) qui va rejeté la piste pour code service inattendu. Ou bien la banque qui va savoir que le commerçant X a un lecteur n'acceptant pas le NFC. Bref on voit qu'il y a de possibles failles en choisissant bien chez qui tenter l'escroquerie.

Autre sécurité, la piste magnétique ainsi créé ne pourra servir qu'une seule fois et avant que l'utilisateur de la carte n'ai fait un paiement avec en NFC. Ça doit laisser un peu de temps tout de même pour s'en servir et faire un gros achat, genre envoyer les données collectées frauduleusement à un cousin aux US qui imprime illico un bande magnétique (facile, la clé de votre hotel est faite comme ça) pour s'en servir dans l'heure qui suit ... oui je vois le mal partout :)


Bref, tout n'est pas tout noir, mais c'est tout de même loin d'être tout blanc.


02 juillet 2014

maven/docker jungle

Docker office in San Francisco looks like a Jungle. I'm not sure that's the sole reason to explain profusion of maven-docker plugins in the wild.


Just searching github (I assume nobody uses google code anymore) gives a dozen candidates, some of them being just empty repositories.

So, here is a quick exploration for available plugins. All of them let you run and stop containers for integration test phase.

Alex Collins (https://github.com/alexec/docker-maven-plugin com.alexecollins.docker). 
Let you build a set of containers as part of a maven build (overriding the docker "build" terminology to follow maven "package" one). Uses a proprietary yaml descriptor, and rely on a custom fork (sic) docker-java client library, that doesn't support unix socket (default docker daemon protocol on localhost). 

Wouter Dance (https://github.com/wouterd/docker-maven-plugin net.wouterdanes.docker)
Comparable to Alex plugin but based on it's own REST client library to talk with docker daemon. So require you to choose between local or remote docker - same issue with unix socket.

Eduardo de Vera Toquero (https://github.com/etux/docker-maven-plugin es.devera.maven.plugins)
Just a maven wrapper to Docker commands

Can create a data container with built artifacts, as define by a (mostly standard) maven assembly descriptor, and then mounted into containers. Uses a custom REST client - still no support for unix socket.

Bilgin Ibryam (https://github.com/bibryam/docker-maven-plugin com.ofbizian)
A wrapper to start and stop existing docker images as part of a maven build. No support for unix socket.

Let you add artifact built by maven to an existing base image, and set entrypoint. Typical use-case is you have a generic base image with your app-server runtime, just need to add the application WAR. Can also use a full Dockerfile. Relies on spotify docker client (not sure about unix socket support, seems not implemented).

Vojtěch Juránek is also working on some plugin, but not released yet.

Imaginate Labs (https://github.com/imaginatelabs/docker-maven-plugin) develop an alpha-stage docker/vagrant plugin. Not sure I like such a combination of a VM manager + Docker within a build.


Most of those plugin are just wrappers to run docker, could just be replaced with maven-exec plugin to run equivalent docker commands, and without restriction on docker daemon unix socket. I don't think it's "cleaner" to write such a docker execution as xml in a pom versus just get the right tool executed as-is. This just introduce expectation to get the same result, but actual differences, like lack of unix socket support and/or docker API mismatch.
So, as a resume, none of those plugins make me feel I need one to use docker within my maven project. Spotify and RHuss plugins are the sole one to hack the docker build process and provide some added value: They both try to concile an actual maven packaging workflow with a docker image build.

Make me also think jenkins way to encourage people to contribute on same github organization and contribute vs re-create existing plugin on their own is a good model. Codehaus Mojo was initially designed for this purpose but clearly isn't attractive/flexible enough to embrace developer enthusiasm.

01 juillet 2014

Carte bleue NFC

Après renouvellement de ma carte bleue j'ai découvert qu'elle était équipée d'une antenne NFC, qui permet le payement sans contact. Première surprise, ce paiement se fait sans que je valide quoi que ce soit, ce qui ne m'a pas tellement plu. Mais je suis rassuré en lisant http://www.cartes-bancaires.com/spip.php?rubrique81 :


Puis-je faire une transaction sans contact sans m’en rendre compte ?
Non, il est impossible d’effectuer un paiement sans contact sans le vouloir. En effet, c’est vous qui déclenchez le paiement en approchant votre carte à moins de 3 à 4 cm du terminal du commerçant pour valider le montant inscrit. Au-delà de cette distance votre carte sans contact ne peut-être activée. Vous restez donc maître de vos paiements sans contact. En outre, toute transaction sans contact se conclue par l’émission d’un ticket de 
caisse.
Ah ben s'il y a un ticket de caisse, alors tout va bien.

Seconde surprise, après quelques recherche : les données de ma carte sont envoyées en clair via le protocole sans fil, sans aucune forme de sécurisation. Un peu comme quand le stagiaire vous dit que le mot de passe est sécurisé par encodage Base64, mais en pire.

Donc en gros, les infos de la bande magnétique de la carte sont exposées sans contact a quiconque passe à proximité. Car si le protocole NFC est limité à quelques cm avec une antenne compacte - comme celle intégrée dans la carte bleue - un récepteur bien pensé et bien amplifié doit permettre de capter sans problème depuis le fond d'une poche ou d'un sac à main en profitant de la promiscuité d'un métro à l'heure de pointe. Vous pouvez lire ici une explication détaillée sur les limites techniques de distance en NFC.

On me répond que le débit est limité à 20€, mais là n'est pas le problème (encore que...). En laissant ainsi mes coordonnées bancaires exposées, je permet à un malveillant mais ingénieux bricoleur (avec un tonton dans la mafia) de collecter des données valides pour fabriquer de vraies-fausses cartes.

Et non, tout le monde n'utilise pas la puce de la carte bleue et la validation par code PIN. Allez faire un tour aux USA pour vous en convaincre - ils sont en avance sur pas mal de sujets, mais clairement sur le payement par carte c'est la préhistoire. En 4 jours à San Francisco pendant Google IO, j'ai effectué une dizaine de paiements par carte par seule lecture de la bande magnétique, et même un avec le "fer à repasser" que les moins de 30 ans n'ont sans doute jamais vu.

Une seule fois (sic) on a noté le code de vérification (les fameux trois derniers chiffres au dos). Par ailleurs, le succès de Square qui se base aussi sur la seule bande magnétique est révélateur.

J'ai adopté une solution un peu radicale pour "désactiver" l'antenne NFC (on peut faire plus propre), sinon il parait qu'on peut demander à sa banque un échange contre une carte sans NFC - avec des frais bien évidemment.

Mais bon rassurez-vous, votre forfait de services bancaires inclut une assurance contre utilisation frauduleuse de votre moyen de payement, bien plus utile que de mettre en place une solution techniquement fiable...





30 juin 2014

Debugging a Docker container

So you can run your (put your favorite language/framework here) application within a Docker container, that's cool. Now, how do you debug it ?

This is feedback I got from my colleague Cyrile, trying to port his Tomcat 8 runtime from RUN@Cloud to a Docker-based environment. He use to integrate the tomcat appserver with syslog and capture thread dumps at runtime with a kill -3 signal sent to the JVM.

Few days ago I'd have suggested him to instrument his Docker image with tons of additional diagnostic tools and extra ports, but I've read Jerôme's blog in the meantime.

So, application is running inside a Docker container :

➜ ~  docker run -d dgageot/helloworld
1cbe9740baa45279eb775d2e0df5a12e5807c112ec382b3bdb20695df429854e

I'll use nsenter and Jerôme docker-enter to add a new diagnostic process to my container. Please remember a container is not a classic Virtual Machine, but "just" a group of process sharing a common Linux kernel namespace. nsenter let you add another process to the group, so can be used to attach a new shell session to the running container.

As I'm running boot2docker and this one don't have nsenter pre-installed (it should imho), I'm installing it directly from Jerôme Docker image :

➜  ~ docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
Unable to find image 'jpetazzo/nsenter' locally
Pulling repository jpetazzo/nsenter
...
Installing nsenter to /target
Installing docker-enter to /target

docker-enter script makes it even easier to use nsenter in a docker context, just need to know the docker image ID. So let's ssh into boot2docker and use this script to access the running container.

➜  ~ boot2docker ssh
Warning: Permanently added '[localhost]:2022' (RSA) to the list of known hosts.
                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \______ o          __/
             \    \        __/
              \____\______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
boot2docker: 1.0.0
             master : 16013ee - Mon Jun  9 16:33:25 UTC 2014


docker@boot2docker:~$ sudo docker-enter 1cbe9740baa45279
# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:12 ?        00:00:04 java -jar target/hello.jar
root        22     0  0 14:19 ?        00:00:00 -sh
root        25    22  0 14:19 ?        00:00:00 ps -ef

I now can use my favorite diagnostic tools to check application health.
# jstack 1
2014-06-30 14:20:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.5-b02 mixed mode):

"Attach Listener" #15 daemon prio=9 os_prio=0 tid=0x00007fbfa0001000 nid=0x25 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

Cool, isn't it ?
As you maybe noticed, this require to be root on host, so for your production server you might consider reading Jerôme's article carefully and consider using the ssh command= option with a dedicated ssh key for production diagnostic.

I'm considering using this exact same mechanism in a Jenkins plugin so user can provide arbitrary image for build environment, without requirement for a sshd server (like docker plugin does).