New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

alexa-verifier

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

alexa-verifier - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

.github/workflows/main.yml

5

CHANGELOG.md

@@ -0,1 +1,6 @@

# 4.0.0
* BREAKING: use sha256 for signature verification, as per https://developer.amazon.com/en-US/docs/alexa/custom-skills/host-a-custom-skill-as-a-web-service.html#check-request-signature. fixes #68
* update `sinon` and `unroll` dev deps
# 3.0.1

@@ -2,0 +7,0 @@ * fix `engines` field in `package.json`

6

index.js

@@ -11,2 +11,3 @@ import crypto from 'crypto'

const SIGNATURE_FORMAT = 'base64'
const CHARACTER_ENCODING = 'utf8'

@@ -21,2 +22,3 @@

fetchCert(options, function (er, pem_cert) {
if (er)

@@ -36,4 +38,4 @@ return callback(er)

function isValidSignature (pem_cert, signature, requestBody) {
const verifier = crypto.createVerify('RSA-SHA1')
verifier.update(requestBody, 'utf8')
const verifier = crypto.createVerify('RSA-SHA256')
verifier.update(requestBody, CHARACTER_ENCODING)
return verifier.verify(pem_cert, signature, SIGNATURE_FORMAT)

@@ -40,0 +42,0 @@ }

{
"name": "alexa-verifier",
"version": "3.0.2",
"version": "4.0.0",
"description": "Verify HTTP requests sent to an Alexa skill are sent from Amazon",

@@ -25,9 +25,10 @@ "main": "index.js",

"node-forge": "^1.2.1",
"validator": "^9.0.0"
"validator": "^13.7.0"
},
"devDependencies": {
"nock": "^9.0.2",
"sinon": "^4.1.5",
"tap": "^15.0.9",
"unroll": "1.4.0"
"esmock": "^2.6.0",
"nock": "^13.0.0",
"sinon": "^17.0.1",
"tap": "^16.0.0",
"unroll": "1.6.0"
},

@@ -34,0 +35,0 @@ "engines": {

# alexa-verifier
[![Build Status](https://travis-ci.org/mreinstein/alexa-verifier.svg?branch=master)](https://travis-ci.org/mreinstein/alexa-verifier)
![tests](https://github.com/mreinstein/alexa-verifier/actions/workflows/main.yml/badge.svg)
Verify HTTP requests sent to an Alexa skill are sent from Amazon.

@@ -6,0 +7,0 @@

import { test } from 'tap'
import crypto from 'crypto'
import esmock from 'esmock'
import fs from 'fs'
import url from 'url'
import verifier from '../index.js'
import sinon from 'sinon'
import { dirname } from 'path'
import { fileURLToPath } from 'url'
const cert_url = 'https://s3.amazonaws.com/echo.api/echo-api-cert-10.pem' // latest valid cert
const __dirname = dirname(fileURLToPath(import.meta.url))
const cert_url = 'https://s3.amazonaws.com/echo.api/echo-api-cert-12.pem' // latest valid cert
const rsaSha256Key = fs.readFileSync(`${__dirname}/mocks/rsa_sha256`).toString()
const validPem = fs.readFileSync(`${__dirname}/mocks/rsa_sha256_pub`).toString()
test('handle missing cert_url parameter', function (t) {

@@ -115,8 +126,23 @@ const signature = 'JbWZ4iO5ogpq1NhsOqyqq/QRrvc1/XyDwjcBO9wWSk//c11+gImmtWzMG9tDEW40t0Xwt1cnGU93DwUZQzMyzJ5CMi+09qVQUSIHiSmPekKaQRxS0Ibu7l7cXXuCcOBupbkheD/Dsd897Bm5SQwd1cFKRv+PJlpmGKimgh2QmbivogsEkFl8b9SW48kjKWazwj/XP2SrHY0bTvwMTVu7zvTcp0ZenEGlY2DNr5zSd1n6lmS6rgAt1IPwhBzqI0PVMngaM0DQhB0wUPj3QoIUh0IyMVAQzRFbQpS4UGrA4M9a5a+AGy0jCQKiRCI+Yi9iZYEVYvfafF/lyOUHHYcpOg=='

test('handle valid signature', function (t) {
const ts = '2017-02-10T07:27:59Z'
test('handle valid signature', async function (t) {
const verifier = await esmock('../index.js', {
'../fetch-cert.js': {
default: function fetchCert (options, callback) {
callback(undefined, validPem)
}
},
'../validate-cert.js': {
default: function validateCert (pem_cert) {
// we're using our mocked sha256 pub/private keypair, so skip all the validation unrelated to
// signature checking.
}
},
})
const ts = '2019-09-01T07:27:59Z'
const now = new Date(ts)
const clock = sinon.useFakeTimers(now.getTime())
const cert_url = 'https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem'
const signature = 'Qc8OuaGEHWeL/39XTEDYFbOCufYWpwi45rqmM2R4WaSEYcSXq+hUko/88wv48+6SPUiEddWSEEINJFAFV5auYZsnBzqCK+SO8mGNOGHmLYpcFuSEHI3eA3nDIEARrXTivqqbH/LCPJHc0tqNYr3yPZRIR2mYFndJOxgDNSOooZX+tp2GafHHsjjShCjmePaLxJiGG1DmrL6fyOJoLrzc0olUxLmnJviS6Q5wBir899TMEZ/zX+aiBTt/khVvwIh+hI/PZsRq/pQw4WAvQz1bcnGNamvMA/TKSJtR0elJP+TgCqbVoYisDgQXkhi8/wonkLhs68pN+TurbR7GyC1vxw=='
const body = {

@@ -147,6 +173,10 @@ "version": "1.0",

verifier(cert_url, signature, JSON.stringify(body), function (er) {
const requestEnvelope = JSON.stringify(body)
const signer = crypto.createSign('RSA-SHA256')
signer.update(requestEnvelope)
const signature = signer.sign(rsaSha256Key, 'base64');
verifier(cert_url, signature, requestEnvelope, function (er) {
t.equal(er, undefined)
clock.restore()
t.end()
})

@@ -156,8 +186,21 @@ })

test('handle valid signature with double byte utf8 encodings', function (t) {
test('handle valid signature with double byte utf8 encodings', async function (t) {
const verifier = await esmock('../index.js', {
'../fetch-cert.js': {
default: function fetchCert (options, callback) {
callback(undefined, validPem)
}
},
'../validate-cert.js': {
default: function validateCert (pem_cert) {
// we're using our mocked sha256 pub/private keypair, so skip all the validation unrelated to
// signature checking.
}
},
})
const ts = '2017-04-05T12:02:36Z'
const now = new Date(ts)
const clock = sinon.useFakeTimers(now.getTime())
const cert_url = 'https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem'
const signature = 'WLShxe8KMwHUt8hVD5+iE4tDO+J8Li21yocDWnq8LVRpE2PMMWCxjQzOCzyoFm4i/yW07UKtKQxcnzB44ZEdP6e6HelwBwEdP4lb8jQcc5knk8SuUth4N7cu6Em8FPOdOJdd9idHbO/p8BTb14wgua5n+1SDKHm+wPikOVsfCMYsXcwRWx5FsgP1wVPrDsCHN/ISiCXz+UuMnd6H0uRNdLZ/x/ikPkknh+P1kuFa2a2LN4r57IwBDAxkdf9MzXEexSOO0nWLnyJY2VAFB+O7JKE39CwMJ1+YDOwTTTLjilkCnSlfnr6DP4HPGHnYhh2HQZle8UBrSDm4ntflErpISQ=='
const body = {

@@ -195,2 +238,7 @@ "version":"1.0",

const requestEnvelope = JSON.stringify(body)
const signer = crypto.createSign('RSA-SHA256')
signer.update(requestEnvelope)
const signature = signer.sign(rsaSha256Key, 'base64');
verifier(cert_url, signature, JSON.stringify(body), function (er) {

@@ -206,6 +254,3 @@ t.equal(er, undefined)

const ts = '2017-04-05T12:02:36Z'
const now = new Date(ts)
const clock = sinon.useFakeTimers(now.getTime())
const cert_url = 'https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem'
const signature = 'Qc8OuaGEHWeL/39XTEDYFbOCufYWpwi45rqmM2R4WaSEYcSXq+hUko/88wv48+6SPUiEddWSEEINJFAFV5auYZsnBzqCK+SO8mGNOGHmLYpcFuSEHI3eA3nDIEARrXTivqqbH/LCPJHc0tqNYr3yPZRIR2mYFndJOxgDNSOooZX+tp2GafHHsjjShCjmePaLxJiGG1DmrL6fyOJoLrzc0olUxLmnJviS6Q5wBir899TMEZ/zX+aiBTt/khVvwIh+hI/PZsRq/pQw4WAvQz1bcnGNamvMA/TKSJtR0elJP+TgCqbVoYisDgQXkhi8/wonkLhs68pN+TurbR7GyC1vxw=='
const signature = ''
const body = {

@@ -212,0 +257,0 @@ "version": "1.0",

@@ -121,3 +121,3 @@ import fs from 'fs'

test('fails on expired certificate (Not After)', function (t) {
const pem = fs.readFileSync(__dirname + '/cert-expired.pem')
const pem = fs.readFileSync(__dirname + '/mocks/cert-expired.pem')
t.ok(validate(pem) === 'invalid certificate validity (past expired date)')

@@ -128,5 +128,5 @@ t.end()

test('approves valid certifcate', function (t) {
const pem = fs.readFileSync(__dirname + '/echo-api-cert-10.cer')
const pem = fs.readFileSync(__dirname + '/mocks/echo-api-cert-12.cer')
t.ok(validate(pem) === undefined, 'Certificate should be valid')
t.end()
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc