Sanctum and choosing how much auth you need

Airlock lived for about a week. Laravel 7 shipped it this month, a trademark scare followed, and it became Sanctum. Fast rename, same idea. And the idea is good, because it names a problem people solve badly. The problem: your own SPA needs to talk to your own API. For years the reflex was OAuth2. Install Passport, stand up an authorization server, issue JWTs to a frontend on the same domain as the backend. All that machinery to authenticate first-party code against itself. OAuth is a delegation protocol, it lets a third party act for a user. When there is no third party, you are running a passport office for your own family. ...

March 26, 2020 · 2 min · Murat Useinov

Anatomy of email verification

email_verified_at, a timestamp. Laravel 5.7 came out this month with email verification built in, and this column is the first thing I noticed. A boolean would cost the same and answer less. A timestamp answers not only whether, but when, and when a support ticket arrives half a year later, “when” is the question. The tutorials say: implement MustVerifyEmail, put the verified middleware on routes, done. True, and boring. The interesting part is how the feature is put together. It is a small example of a cross-cutting feature done right. ...

September 18, 2018 · 2 min · Murat Useinov

.env is not a secrets store

A .env file committed to git, “temporarily”. Database password, API keys, mailer credentials, all in one file. Symfony 4 moved configuration to environment variables, and this is the second project this month where I see the same thing. .env is a developer convenience. It exists so local setup does not require exporting fifteen variables by hand before running the app. That is the whole job of this file. .env.dist goes to git with placeholder values, .env stays in .gitignore with your local ones. This part is not negotiable. ...

March 14, 2018 · 2 min · Murat Useinov

Sodium in PHP 7.2 core

PHP 7.2 came out on the last day of November. Mcrypt is out of core, libsodium is in. That trade alone makes it a good release. Search any forum for “php encrypt” and you find the same folk recipe: openssl_encrypt with AES-256-CBC, an IV made from who knows what, no authentication of the ciphertext. Every choice in that recipe is a place to be wrong, and CBC without a MAC is wrong in a way that has published attacks. The developer is not careless. The API hands an application developer decisions that belong to a cryptographer. ...

December 10, 2017 · 2 min · Murat Useinov

Host header is user input

$link = 'https://'.$_SERVER['HTTP_HOST'].'/reset/'.$token; I wrote this line. More than once. It builds the link for a password reset email, and it looks like it reads something about the server. It does not. Host comes from the client, same as any other header. Kohana 3.3.4 shipped this month with a fix around exactly this, and the topic is bigger than one framework. The attack is short. Someone requests a password reset for your email address and puts his own domain into the Host header. The application trusts the header, builds the link, sends it. You receive a real email from a real site with a link to evil.example and your real token in the path. You click. He collects the token. Host header poisoning, and no framework protects you from it out of the box. ...

December 23, 2014 · 2 min · Murat Useinov

Debug toolbar in production is a gift to strangers

/_profiler on a live site. Type it after any Symfony domain and sometimes it answers. This autumn the story went around, and I will not retell it. The lesson is bigger than one framework. Think what a profiler actually stores. Every SQL query with parameters. Cookies and session data. Routes, controller names, request headers. Sometimes config values. A full X-ray of your application, nicely formatted, with search. Now count how many sites have /_profiler or a debugbar open to the world because someone deployed with app_dev.php, or left debug = true in the production config. Not a rare exotic mistake. I saw it. I made it once, on a staging server that stayed reachable from outside longer than anyone planned. ...

December 9, 2014 · 2 min · Murat Useinov