gaiterjones / amazon-alexa-php-hello-world-example

Amazon Alexa PHP Hello World Example
16 stars 14 forks source link

Issues with skill endpoint validation #3

Closed mrtomnguyen closed 7 years ago

mrtomnguyen commented 7 years ago

have you tried to submit the skill? this is what Amazon sent me:

"The skill does not validate the signature for the incoming requests and is accepting requests with invalid signature specified."

gaiterjones commented 7 years ago

I have not published any skills yet. I will look into this problem.

mrtomnguyen commented 7 years ago

for testing, it works fine and i do see the .pem in the cache. but i notice after submission, I see another .pem but its 0 kb empty.

gaiterjones commented 7 years ago

I guess I will have to submit a skill to troubleshoot this further, not sure what is happening. The second pem must be generated through the checks they are doing...

gaiterjones commented 7 years ago

We are creating the pem from

md5($_SERVER['HTTP_SIGNATURECERTCHAINURL']);

There is no check if md5($_SERVER['HTTP_SIGNATURECERTCHAINURL']); is set, or has data, this would create an empty pem. Perhaps we need to validate md5($_SERVER['HTTP_SIGNATURECERTCHAINURL']) as well

gaiterjones commented 7 years ago

Try adding the following before the "Determine if we need to download a new Signature Certificate Chain from Amazon" comment in AlexaRequrst.php

// validate signature data key // if (!isset($_SERVER['HTTP_SIGNATURECERTCHAINURL'])) { throw new \Exception('HTTP_SIGNATURECERTCHAINURL key not present'); }

// validate signature data //
if (empty($_SERVER['HTTP_SIGNATURECERTCHAINURL'])) { throw new \Exception('HTTP_SIGNATURECERTCHAINURL data not present'); }

gaiterjones commented 7 years ago

Also, instead of throwing exceptions can you try simply exiting. The exception returns an alexa response which is more designed to provide friendly errors when something in the intent processing goes wrong, with these validation errors amazon probably does not expect us to respond with valid response json.

gaiterjones commented 7 years ago

I have made these changes and updated AlexaRequest.php if you can test if for me that would be cool!

mrtomnguyen commented 7 years ago

so my question is why would their check request returns 0kb .pem ? so you think it's failing because the existing 0kb .pem is cached and Amazon returns error? every user will have a unique .pem right?

gaiterjones commented 7 years ago

Like I said the code wasn't checking for valid HTTP_SIGNATURECERTCHAINURL data and would create the .pem even if no SIGNATURECERTCHAINURL data was present. We are now checking for valid SIGNATURECERTCHAINURL data before trying to create the pem file.

mrtomnguyen commented 7 years ago

ok ive added it. so what happens when this is true? throw new \Exception('HTTP_SIGNATURECERTCHAINURL data not present');

mrtomnguyen commented 7 years ago

I'm still seeing the 0kb .pem Certification still failing. Here's the message:

Issues with skill endpoint validation

The skill does not validate the signature for the incoming requests and is accepting requests with invalid signature specified. Please refer to the document that describes how to build your Alexa Skill as a web service (available via this link: https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-web-service) for tips and requirements about validating the requests (and their signatures) sent to your web service.

mrtomnguyen commented 7 years ago

im gonna try to change the endpoint to the original azurewebsites and maybe that will fix the certificate issues. i was using a redirected ssl for domain.

mrtomnguyen commented 7 years ago

maybe the tips here may help. he discussed "Validating the signature of Alexa requests"

http://www.macadamian.com/2016/03/24/creating-a-new-alexa-skill/

gaiterjones commented 7 years ago

Unforuately the info there is for node.js. Its difficult for me to troubleshoot this as I have not yet submitted an app for public use. all my alexa apps are private.

mrtomnguyen commented 7 years ago

i think i know whats going on. upon submission, amazon does a check of sending an invalid request with Empty PEM. this is why i keep seeing the 0kb .pem immediately after submission. if the skill accept the invalid request, it fails. so ive updated the code to check for empty, hope this fixes it. i've checked your code and everything else looks right. **i'ev just resubmitted it and no 0kb .pem so far.

            // validate signature data      
            if (empty($_SERVER['HTTP_SIGNATURECERTCHAINURL']) || 
                $_SERVER['HTTP_SIGNATURECERTCHAINURL']=='null' ||
                $_SERVER['HTTP_SIGNATURECERTCHAINURL']=='')
            {
                throw new \Exception('HTTP_SIGNATURECERTCHAINURL data not present');
            }

its discussed here. https://github.com/AreYouFreeBusy/AlexaSkillsKit.NET/issues/5

gaiterjones commented 7 years ago

This is what I thought, didnt think to check for a null value though. Cool, good work! Please let me know if your app passes the validation and I will update my code. The link you provided documents a method of testing the signature validation yourself so that will be very useful for tesing.

gaiterjones commented 7 years ago

Did you see the string 'null' when you were testing? To check for null usually you would use is_null() or ==null, in your code =='null' checks for a string containing the word 'null' and not a null value.

Did your skill submit?

mrtomnguyen commented 7 years ago

certification pending. but i just saw the 0kb pem so ive updated to this:

            // validate signature data      
            if (empty($_SERVER['HTTP_SIGNATURECERTCHAINURL']) || 
                $_SERVER['HTTP_SIGNATURECERTCHAINURL']==null ||
                is_null($_SERVER['HTTP_SIGNATURECERTCHAINURL']) ||
                $_SERVER['HTTP_SIGNATURECERTCHAINURL']=='')
            {
                throw new \Exception('HTTP_SIGNATURECERTCHAINURL data not present');
            }
gaiterjones commented 7 years ago

I have updated AjaxRequest.php on github, it will also now return the correct 400 bad request when validation fails, I have also included the curl command to test validation, you will see the command when you go to alexa.php?debug

On 8 May 2017 at 16:30, Tom Nguyen notifications@github.com wrote:

certification pending. but i just saw the 0kb pem so ive updated to this:

      // validate signature data      
      if (empty($_SERVER['HTTP_SIGNATURECERTCHAINURL']) ||
          $_SERVER['HTTP_SIGNATURECERTCHAINURL']==null ||
          is_null($_SERVER['HTTP_SIGNATURECERTCHAINURL']) ||
          $_SERVER['HTTP_SIGNATURECERTCHAINURL']=='')
      {
          throw new \Exception('HTTP_SIGNATURECERTCHAINURL data not present');
      }

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/gaiterjones/amazon-alexa-php-hello-world-example/issues/3#issuecomment-299883271, or mute the thread https://github.com/notifications/unsubscribe-auth/ADuo_ocMaly4BuhiSj8iHyJm1qpTImzkks5r3ycXgaJpZM4NR8gO .

gaiterjones commented 7 years ago

Can you send me the log files so I can see what amazon are sending in the header for the validation attempts?

gaiterjones commented 7 years ago

I have made another update as there was an error in the validation order

        // Validate proper format of Amazon provided certificate chain url
        //
        $this->validateKeychainUri($_SERVER['HTTP_SIGNATURECERTCHAINURL']);

this should come before the pem file is created. You need to also change this as it will most certainly be causing problems!

mrtomnguyen commented 7 years ago

for some reason, the 0kb request isnt in the cache. the issue is still there so ive updated to this latest codes. ill submit again.

mrtomnguyen commented 7 years ago

ok i haven't seen the 0kb pem yet this last submission. maybe this one works.

gaiterjones commented 7 years ago

I am pretty sure it will work this time.

mrtomnguyen commented 7 years ago

Failed endpoint validation. Not in office to check the pem yet. Not sure what the issue is now.

gaiterjones commented 7 years ago

Did you completely update your AlexaRequest.php file to the latest version?

mrtomnguyen commented 7 years ago

No. Just ValidateAlexaRequest because it wasn't working when I changed the functions before it. What's new in those?

mrtomnguyen commented 7 years ago

can you try to submit a skill? chance is high that you wont pass for other issues but at least you can test the Certificate issue.

the feedback was a bit different this time:

"The skill end-point is not accepting valid signed requests. Please make sure that your signature URL validation is correct and also, the skill end-point is not validating the signatures for incoming requests and is accepting requests with an invalid signature URL specified. Please refer to the following documentation on how to build your Alexa Skill as a web service and validate requests and signatures."

mrtomnguyen commented 7 years ago

emailed you. i've contacted them for more details. hopefully they'll respond soon.

gaiterjones commented 7 years ago

As of version 0.1.0 the security validation elements of the script pass Amazons audit and requirements for submitting and publishing a public Alexa Skill. Thanks to Mr Tom for helping iron out the bugs in the script.