upyx/uri-signature

Sing and verify URIs.

1.1.0 2022-01-24 15:56 UTC

README

Sing and verify URIs.

Source Code Download Package PHP Programming Language Read License Build Status Codecov Code Coverage Psalm Type Coverage

About

A simple tool to sing and verify URIs' query parameters to protect them from fraud. It supports different hash algorithms including HMAC.

It depends on PRS-7 HTTP message implementation. It has been tested with Guzzle and Nyholm, but you can try anyone.

Installation

Install this package as a dependency using Composer.

composer require upyx/uri-signature

If you got an error Could not find package psr/http-message-implementation, it means you miss a PSR-7 implementation. Try

composer require nyholm/psr7

or

composer require guzzlehttp/psr7

Usage

To sign query parameters

use GuzzleHttp\Psr7\Uri;
use Upyx\UriSignature\Signer;
$signer = new Signer('sig', 's0me$ecret!', 'sha1');

$uri = new Uri('https://example.com/?sensitive=value');
$signed = $signer->signUriParams($uri);
echo $signed; // https://example.com/?sensitive=value&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY

To check them

use GuzzleHttp\Psr7\Uri;
use Upyx\UriSignature\Signer;
$signer = new Signer('sig', 's0me$ecret!', 'sha1');

$signed = new Uri('https://example.com/?sensitive=value&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY');
$verified = $signer->verifyUriParams($signed); // true

$hacked = new Uri('https://example.com/?sensitive=changed&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY');
$failed = $signer->verifyUriParams($hacked); // false

It signs query parameters only!

use GuzzleHttp\Psr7\Uri;
use Upyx\UriSignature\Signer;
$signer = new Signer('sig', 's0me$ecret!', 'sha1');

$signed1 = new Uri('//some.example.com/?sensitive=value&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY');
$signed2 = new Uri('//other.example.com/?sensitive=value&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY');
$signed3 = new Uri('/?sensitive=value&sig=YQ_1AXL5Cdspng1W7SETkdvsLoY');

$verified = $signer->verifyUriParams($signed1); // true
$verifiedToo = $signer->verifyUriParams($signed2); // true
$verifiedAgain = $signer->verifyUriParams($signed3); // true

Parameters are being sorted so that the order is not important

use GuzzleHttp\Psr7\Uri;
use Upyx\UriSignature\Signer;
$signer = new Signer('sig', 's0me$ecret!', 'sha1');

$signed1 = new Uri('/?param1=value1&param2=vA%20e.&sig=m3EaBLndIFulvWGJqUuxGepv000');
$signed2 = new Uri('/?param2=vA%20e.&param1=value1&sig=m3EaBLndIFulvWGJqUuxGepv000');

$verified = $signer->verifyUriParams($signed1); // true
$verifiedToo = $signer->verifyUriParams($signed2); // true

However, ordering of arrays is

use GuzzleHttp\Psr7\Uri;
use Upyx\UriSignature\Signer;
$signer = new Signer('sig', 's0me$ecret!', 'sha1');

$signed = new Uri('https://example.com/?param[]=1&param[]=2&sig=TZEYycd_uldtq0B3nHXlETRxT2Y');
$hacked = new Uri('https://example.com/?param[]=2&param[]=1&sig=TZEYycd_uldtq0B3nHXlETRxT2Y');

$verified = $signer->verifyUriParams($signed1); // true
$failed = $signer->verifyUriParams($hacked); // false

To check the supported algorithms, the functions hash_algos() and hash_hmac_algos() can be used. To use HMAC add the hmac- prefix. For example:

new Signer('sig', 's0me$ecret!', 'sha1');
new Signer('sig', 's0me$ecret!', 'md5');
new Signer('sig', 's0me$ecret!', 'hmac-sha1');
new Signer('sig', 's0me$ecret!', 'hmac-md5');

Contributing

Contributions are welcome! To contribute, please familiarize yourself with CONTRIBUTING.md.

Copyright and License

The upyx/uri-signature library is copyright © Sergey Rabochiy and licensed for use under the terms of the MIT License (MIT). Please see LICENSE for more information.