security

All my posts about security.

URL signing in Laravel

The project I'm currently working on will have to send out mails to all its users on a regular basis. It's not a newsletter: the contents of each mail will be very specific to each user. The mail also should contain a link to unsubscribe the user from simular future mails.

The link could look like this: https://myapp.com/unsubscribe. Clicking on the link would direct the user to a login page. After the user has logged in the unsubscribe can be automatically performed. In my mind requiring the user to login first in order to unsubscribe from something isn't very user friendly.

This can be improved by adding the id of the user to the link. Here's what that could look like: https://myapp.com/user/1/unsubscribe. With this link you the app can unsubscribe the user with id 1 in one go. That'll work, but it's not very secure. Unsubscribe links for all other users can be easily guessed. Such links can be made more secure by adding a signature and an expiry date on them.

My colleague Sebastian coded up a Laravel package to create signed url's with a limited lifetime. Here's example where the url gets signed and made valid for only one day:


echo UrlSigner::sign('https://myapp.com/user/1/unsubscribe', 1);

This outputs an url that looks like: https://myapp.com/user/1/unsubscribe?expires=1123690544&signature=93e02326d75

The validate-method can be used the determine if a signed url is (still) valid:


$isValidUrl = UrlSigner::validate($theSignedUrlInTheExampleAbove);

The signature is calculated using the original url itself, the expiration date and a secret string that's specific to your project. When a malicious user tries to change any part of the url the signature won't match up.

I'm assuming that the most common use case of signing url's is to protect routes. The package supplies a middleware that protects routes from invalid signed url's. In the following example only requests with a valid signed url will hit the controller:


Route::get('unsubscribe', ['middleware' => 'signedurl', 'uses => 'UserController@unsubscribe']);

If you're interested in using the package, take a look at it on GitHub: https://github.com/spatie/laravel-url-signer

There's also a framework agnostic version: https://github.com/spatie/url-signer

E-mails can be intercepted and are never 100% secure. Bearing that fact in mind you should never use this kind of link for any destructive action.

EDIT: Some fellow developers pointed out that I could also obfuscate the id in the url. Here are two good libraries to do that:

When using obfuscation of the id this url `https://myapp.com/user/1/unsub `would become something like: `https://myapp.com/user/kwxgqu5w/unsub`

And sure enough, the unsubscribe links of other users cannot be easily guessed. A small downside however is that the url becomes less readable. The big disadvantage is that the url will remain valid forever. As these links through an unsafe medium I think it's a good idea to give them a limited lifetime. Signing an url will do that.

Read more

Join 9,500+ smart developers

Get my monthly newsletter with what I learn from running Spatie, building Oh Dear, and maintaining 300+ open source packages. Practical takes on Laravel, PHP, and AI that you can actually use.

No spam. Unsubscribe anytime. You can also follow me on X.

certificatechain.io: an online tool to download intermediate ssl certificates

When installing an SSL certificate on your server you should install all intermediate certificates as well. If you fail to do so, some browsers will reported “untrusted” warnings for your site like this one.

untrusted

Searching and downloading those intermediate certificates can be a hassle.

Today my colleagues at Spatie and I launched certificatechain.io. This online tool helps you download all intermediate certificates. Just paste or upload your certificate and you'll get a file containing the entire trust chain that you can install on your server.

The site is built with Laravel 5 and uses the SSL certificate chain resolver we made last month.

Read more

An SSL certificate chain resolver original

by Freek Van der Herten – 1 minute read

When installing an SSL certificate on your server you should install all intermediate certificates as well. If you fail to do so, some browsers will reported "untrusted" warnings for your site like this one: Searching and downloading those intermediate certificates can be a hassle. It…

Read more

Automatically reject packages with known security vulnerabilities

This package ensures that your application doesn't have installed dependencies with known security vulnerabilities.

...

The checks are only executed when adding a new dependency via composer require or when running composer update: deploying an application with a valid composer.lock and via composer install won't trigger any security versions checking.

https://github.com/Roave/SecurityAdvisories

Awesome idea! It works by leveraging the "conflict"-property in the composer.json-file of the package.

Read more

Add Two-Factor authentication to your Laravel application

Authy makes it easy to integrate two-factor authentication into your existing Laravel application. It's user-end implementation is versitile, offering support for both smart-phones and standard phones. Furthermore, implmentation with its API is easy and seamless. Finally, its analytics and data tracking can you provide insights into your users and how they interact with your application's authentication system.

This tutorial assumes that you have an Authy developer account (which can be created here ), an application (either testing or production), and your application's API key.

http://blog.enge.me/post/installing-two-factor-authentication-with-authy

Read more