alexa-skills-kit-sdk-for-nodejs icon indicating copy to clipboard operation
alexa-skills-kit-sdk-for-nodejs copied to clipboard

ExpressAdapter.verifySignature causes skills to fail validation

Open stx opened this issue 3 years ago • 9 comments
trafficstars

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:

Expected Behavior

The skill passes validation with verifySignature enabled.

Current Behavior

new ExpressAdapter(skillBuilder.create(), true, true) causes validation to fail in the Alexa console. The error is below.

The skill is rejecting the request when executed with additional properties in the JSON request.

When we invoke the skill with additional parameters, the skill is rejecting it when we expect this to be accepted. Future versions of the Alexa Skills Kit may add new properties to the JSON request and response formats, while maintaining backward compatibility for the existing properties. Your code must be resilient to these types of changes. For example, your code for de-serializing a JSON request must not break when it encounters a new, unknown property. Please ensure that your code can handle new attributes and does not break when it encounters new properties in the JSON request.

Possible Solution

None.

Steps to Reproduce (for bugs)

Fails validation via the Alexa console: new ExpressAdapter(skillBuilder.create(), true, true)

Passes validation via the Alexa console: new ExpressAdapter(skillBuilder.create(), false, true)

Failing request:

Alexa Request Body:

{"version":"1.0","session":{"new":true,"sessionId":"SessionId.fdaac61a-0055-4dfb-98e1-dbe689d9053f","application":{"applicationId":"amzn1.ask.skill.cba40848-ed70-4b8f-847c-7d367025aa36"},"user":{"userId":"amzn1.ask.account.AEZW5CNUZ7V6KZXG2HDY7G3IRAODLGU3YAH6RXQ5MT7OVUJPDIZA7RQZMKMZWWM2XERRRTWWX6KCBHEERZWM5KY37YXX6HEDZCUOUALA5ZFMZ5Y4GP7MYRVMSI4ZEYS4T5ECVGHTPDJDKSFEA2FFYFCHRG3XZQWD3THHXASSTD5NK4LT4DJVR75EYPUDM22KOHC4LGC7VF2QJNA"}},"context":{"AudioPlayer":{"offsetInMilliseconds":0,"token":null,"playerActivity":"IDLE"},"System":{"application":{"applicationId":"amzn1.ask.skill.cba40848-ed70-4b8f-847c-7d367025aa36"},"user":{"userId":"amzn1.ask.account...."},"device":{"deviceId":"amzn1.ask.device.AGE76YTRDWVKIL2YD46NMOPUMR4SFSFQVPDNDQVBIPOCKVS3IFLUGZ5OFFHSGQ7CSR3F5FLFX67KQTF3OCMVCACCQWGMY7L4AVRWYQQEDULK3FUL4DBOBSAE4HMACFQRIRJITOY7SABRUJSRFOIIEZCENIKA","supportedInterfaces":{"AudioPlayer":{}}},"apiEndpoint":"https://api.amazonalexa.com","apiAccessToken":"..."}},"request":{"type":"LaunchRequest","requestId":"amzn1.echo-api.request.f8ccab9a-5cd2-4ece-aa29-26c26a50a73b","timestamp":"2022-06-01T18:22:04Z","locale":"en-GB","body":null,"payload":null,"shouldLinkResultBeReturned":false,"_utteranceId":null},"certificationParam1":"hello","certificationParam2":"10000"}

Response Code: 400

Response Body: "AskSdk.Request verification failed Error, request body and signature does not match"

Context

This is blocking our production releases.

Your Environment

express 5.0.0-beta.1 ask-sdk-core 2.12.1 ask-sdk-express-adapter 2.12.1 ask-sdk-model 1.38.2 ask-sdk-runtime 2.12.0

  • Operating System and version: Docker node:14-slim

Node.js and NPM Info

  • Node.js version used for development: Docker node:14-slim
  • NPM version used for development: 8.1.0

stx avatar Jun 01 '22 18:06 stx

can you elaborate on the extra parameters that are getting appended to the Body? these are serialized into a request envelope as long as you have the matching ask-sdk-model with those extra parameters you should be able to serialize/deserialize and validate the body.

doiron avatar Jun 01 '22 19:06 doiron

can you elaborate on the extra parameters that are getting appended to the Body? these are serialized into a request envelope as long as you have the matching ask-sdk-model with those extra parameters you should be able to serialize/deserialize and validate the body.

The Alexa console doesn't say what the request is, or what the parameters are, or really what it's even doing. It's just part of an automated process prior to every skill release.

I reverse engineered all of the requests being sent by that process and included the problematic request above. I suspect this is what's being added:

"certificationParam1":"hello","certificationParam2":"10000"

stx avatar Jun 01 '22 20:06 stx

Perhaps one of these changes in Express 5 is breaking the validator? https://expressjs.com/en/guide/migrating-5.html

Maybe the req.host change or another undocumented update?

stx avatar Jun 01 '22 20:06 stx

oh those ones thanks for clarifying this. I believe these are part of the certification tests. will investigate this further with the certification team.

doiron avatar Jun 01 '22 21:06 doiron

I'm using these packages and facing the same issue.

"express": "^4.16.3",
"ask-sdk-core": "^2.11.0",
"ask-sdk-express-adapter": "^2.11.0",
"ask-sdk-model": "^1.37.1",

I had to change my code like this to submit. alexa

CasperPas avatar Jul 05 '22 10:07 CasperPas

@doiron We're unable to submit updates to production Alexa skills because of this issue and we've found no workaround, including downgrading to Express 4. Disabling the verifySignature and verifyTimestamp flags will result in additional certification failures, which also prevent submission.

As far as we can tell, there is now no way to submit or update Alexa skills using the Express Adapter in this package. Can you provide a workaround please? Thank you!

stx avatar Jul 11 '22 18:07 stx

For others running into this issue, here's our fix:

In dist/verifier/index.js, change:

        if (!verifier.verify(pemCert, signature, SIGNATURE_FORMAT)) {
            throw new Error('request body and signature does not match');
        }

to

        if (!verifier.verify(pemCert, signature, SIGNATURE_FORMAT)) {
            // Fix for https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/issues/717
            if (JSON.stringify(requestEnvelope).includes('certificationParam')) {
                return;
            }

            throw new Error('request body and signature does not match');
        }

You'll now be able to submit Alexa skills.

stx avatar Jul 13 '22 08:07 stx

+1

I'm facing the same problem here, is there any ETA for the solution?

devsdmf avatar Jul 27 '22 03:07 devsdmf

Same here, is there something we are missing? Should we try doing: `const { SkillRequestSignatureVerifier, TimestampVerifier } = require('ask-sdk-express-adapter');

const skillBuilder = Alexa.SkillBuilders.custom();
const skill = skillBuilder.create();

// This code snippet assumes you have already consumed the request body as text and headers
try {
    await new SkillRequestSignatureVerifier().verify(textBody, requestHeaders);
    await new TimestampVerifier().verify(textBody);
} catch (err) {
    // server return err message
}
const response = skill.invoke(JSON.parse(textBody));
// server send response in Json format`

like its indicated in https://developer.amazon.com/en-US/docs/alexa/alexa-skills-kit-sdk-for-nodejs/host-web-service.html

garciaraul85 avatar Jul 27 '22 20:07 garciaraul85

I believe we have identified the issue with the Alexa certification requests. The mitigation is now in production, you should be able to try upgrading again or re-introducing the validation to help secure your skill.

doiron avatar Sep 02 '22 23:09 doiron

Yep, Alexa backend fixed now. Thanks!

stx avatar Oct 14 '22 22:10 stx