nayzo/NzoUrlEncryptorBundle

Route default values should not be decrypted

Closed this issue · 6 comments

Hello,

I have a route parameter that defaults to null, set like this:

<?php

namespace AppBundle\Test;

use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Nzo\UrlEncryptorBundle\Annotations\ParamDecryptor;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class TestController extends Controller {

    /**
     * @Route(
     *      "/url-param-encryptor-test/{id}",
     *      name="url_param_encryptor_test"
     * )
     * @ParamDecryptor(params="id")
     *
     * @param Request $request
     * @param int $id
     * @return Response
     */
    public function testUrlParamEncryptor(Request $request, $id = null){

        /** @var \Nzo\UrlEncryptorBundle\UrlEncryptor\UrlEncryptor $nzo */
        $nzo = $this->get('nzo_url_encryptor');

        dump('// decrypted $id');
        dump($id);

        dump('// decrypt( null )');
        dump($nzo->decrypt(null));

        $enc = $nzo->encrypt(null);
        $dec = $nzo->decrypt($enc);
        dump('// decrypt(encrypt(null))');
        dump($dec);

        return new Response('Done!');
    }
}

Seems like the decryptor decrypts the default value. First, I thought I should use the encrypted value of null as default, but this doesn't seem like a good practice, because changing the secret key would render unexpected results. Do you have any suggestion regarding this issue? Can I stop it from decrypting the default values?

Thanks!

nayzo commented

I think you did not encrypt your {id} in your template so that when it called in the controller action it will get decrypted by the ParamDecryptor annotation service. Furthermore in your example you did a decryption on a non encrypted data witch I think it's not what you want to do...

About the encryption and decryption of the null value, here an example that may clarify the behaviour:

//...
$nzo = $this->get('nzo_url_encryptor');
$nullEncrypted = $nzo->encrypt(null);
var_dump($nullEncrypted); // ==> it will return something like : '9XYljFhSQEs'
var_dump($nzo->decrypt($nullEncrypted)); // ==> it will return '' (empty value)

Hope that answer your questions.

Hi,
Thank you for your answer!

Reading my message makes me realize it's an incomplete description of the problem. You're right, the {id} was not encrypted at all. I was referring to situations when the parameter is missing and the default value should kick in.

For example, if you access the route /url-param-encryptor-test/9XYljFhSQEs, where 9XYljFhSQEs is an encrypted id, even if the original unencrypted value was null everything works great, but when you access /url-param-encryptor-test without an encrypted {id} parameter, expecting the route to use the default value given in the method's definition $id = null, it won't work, regardless of the default value. It could be null, 123456, 'some-string', true or whatever you can think of.

In the sample code I decrypted non encrypted data, just to give an example of what actually happens with the {id} default parameter value. The bundle decrypts it even though is was not encrypted.

If instead of:

public function testUrlParamEncryptor(Request $request, $id = null) {
    // ...
}

I use:

public function testUrlParamEncryptor(Request $request, $id = '9XYljFhSQEs') {
    // ...
}

Everything is goot, but I think this is not a good solution, is more like a hack, because if you change the secret at some point, this won't work anymore, so it's a flawed solution.

To conlcude, I think the default parameters values should not be decrypted at all or use some mechanism to identify if it happened and revert it somehow to the correct value, if it's possible.

A fix I can think of would be to pass the annotation with default values like this:

/**
     * @Route(
     *      "/url-param-encryptor-test/{id}",
     *      name="url_param_encryptor_test"
     * )
     * @ParamDecryptor(params={"id": [DEFAULT_VALUE_HERE]})
     *
     * @param Request $request
     * @param int $id
     * @return Response
     */
nayzo commented

Ok, I get it now, I will fix that very soon,
I'll keep this issue open until the fix
Thanks 👍

nayzo commented

fixed: #14
You need to upgrade to the ~2.0 major version, see the README.md file for more info.

That was fast! 👍

Thanks!