Skip to content

Commit e91bcb1

Browse files
committed
fix: allow access to devices only by public ID
Device ID should never be allowed to use as access key, because it can be guessed.
1 parent f13e534 commit e91bcb1

25 files changed

+224
-163
lines changed

cdk/BackendStack.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ export class BackendStack extends Stack {
7171
description: 'name of the public devices table',
7272
value: publicDevices.publicDevicesTable.tableName,
7373
})
74+
new CfnOutput(this, 'publicDevicesTableIdIndexName', {
75+
exportName: `${this.stackName}:publicDevicesTableIdIndexName`,
76+
description: 'name of the public devices table id index',
77+
value: publicDevices.idIndex,
78+
})
7479

7580
const api = new API(this)
7681
api.addRoute(
@@ -192,6 +197,7 @@ export type StackOutputs = {
192197
*/
193198
gatewayDomainName?: string
194199
publicDevicesTableName: string
200+
publicDevicesTableIdIndexName: string
195201
/**
196202
* Role ARN to use in the deploy GitHub Actions Workflow
197203
*/

cdk/resources/CustomDevicesAPI.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export class CustomDevicesAPI extends Construct {
6666
BACKEND_STACK_NAME: STACK_NAME,
6767
OPENSSL_LAMBDA_FUNCTION_NAME: openSSLFn.functionName,
6868
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
69+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
6970
},
7071
...new LambdaLogGroup(this, 'createCredentialsFnLogs'),
7172
initialPolicy: [SettingsPermissions(Stack.of(this))],

cdk/resources/DevicesAPI.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class DevicesAPI extends Construct {
3434
environment: {
3535
VERSION: this.node.getContext('version'),
3636
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
37+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
3738
PUBLIC_DEVICES_TABLE_MODEL_OWNER_CONFIRMED_INDEX_NAME:
3839
publicDevices.publicDevicesTableModelOwnerConfirmedIndex,
3940
NODE_NO_WARNINGS: '1',

cdk/resources/LwM2MShadow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export class LwM2MShadow extends Construct {
4343
environment: {
4444
VERSION: this.node.getContext('version'),
4545
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
46+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
4647
},
4748
initialPolicy: [
4849
new IAM.PolicyStatement({

cdk/resources/SenMLMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class SenMLMessages extends Construct {
6161
environment: {
6262
VERSION: this.node.getContext('version'),
6363
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
64+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
6465
IMPORT_LOGS_TABLE_NAME: importLogs.tableName,
6566
},
6667
initialPolicy: [

cdk/resources/ShareAPI.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class ShareAPI extends Construct {
4545
environment: {
4646
VERSION: this.node.getContext('version'),
4747
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
48+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
4849
FROM_EMAIL: `notification@${domain}`,
4950
NODE_NO_WARNINGS: '1',
5051
IS_TEST: this.node.getContext('isTest') === true ? '1' : '0',
@@ -83,6 +84,7 @@ export class ShareAPI extends Construct {
8384
environment: {
8485
VERSION: this.node.getContext('version'),
8586
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
87+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
8688
NODE_NO_WARNINGS: '1',
8789
},
8890
...new LambdaLogGroup(this, 'confirmOwnershipFnLogs'),
@@ -101,6 +103,7 @@ export class ShareAPI extends Construct {
101103
environment: {
102104
VERSION: this.node.getContext('version'),
103105
PUBLIC_DEVICES_TABLE_NAME: publicDevices.publicDevicesTable.tableName,
106+
PUBLIC_DEVICES_ID_INDEX_NAME: publicDevices.idIndex,
104107
NODE_NO_WARNINGS: '1',
105108
},
106109
...new LambdaLogGroup(this, 'sharingStatusFnLogs'),

cli/cli.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,20 @@ const CLI = async ({ isCI }: { isCI: boolean }) => {
6464
console.error('Running on CI...')
6565
} else {
6666
try {
67-
const mapOutputs = await stackOutput(cf)<StackOutputs>(STACK_NAME)
67+
const backendOutputs = await stackOutput(cf)<StackOutputs>(STACK_NAME)
6868
commands.push(
6969
registerCustomMapDevice({
7070
db,
71-
publicDevicesTableName: mapOutputs.publicDevicesTableName,
71+
publicDevicesTableName: backendOutputs.publicDevicesTableName,
72+
idIndex: backendOutputs.publicDevicesTableIdIndexName,
7273
ssm,
7374
env: accountEnv,
7475
stackName: STACK_NAME,
7576
}),
7677
shareDevice({
7778
db,
78-
publicDevicesTableName: mapOutputs.publicDevicesTableName,
79+
publicDevicesTableName: backendOutputs.publicDevicesTableName,
80+
idIndex: backendOutputs.publicDevicesTableIdIndexName,
7981
}),
8082
)
8183
} catch (error) {

cli/commands/register-custom-device.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import chalk from 'chalk'
66
import { randomUUID } from 'node:crypto'
77
import fs from 'node:fs/promises'
88
import path from 'node:path'
9-
import { publicDevicesRepo } from '../../sharing/publicDevicesRepo.js'
9+
import { publicDevicesRepo } from '../../devices/publicDevicesRepo.js'
1010
import { createCA } from '@hello.nrfcloud.com/certificate-helpers/ca'
1111
import { createDeviceCertificate } from '@hello.nrfcloud.com/certificate-helpers/device'
1212
import type { CommandDefinition } from './CommandDefinition.js'
@@ -21,12 +21,14 @@ export const registerCustomMapDevice = ({
2121
stackName,
2222
db,
2323
publicDevicesTableName,
24+
idIndex,
2425
env,
2526
}: {
2627
ssm: SSMClient
2728
stackName: string
2829
db: DynamoDBClient
2930
publicDevicesTableName: string
31+
idIndex: string
3032
env: Required<Environment>
3133
}): CommandDefinition => ({
3234
command: 'register-custom-map-device <model> <email>',
@@ -43,6 +45,7 @@ export const registerCustomMapDevice = ({
4345
const publicDevice = publicDevicesRepo({
4446
db,
4547
TableName: publicDevicesTableName,
48+
idIndex,
4649
})
4750
const maybePublished = await publicDevice.share({
4851
deviceId,

cli/commands/share-device.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import type { DynamoDBClient } from '@aws-sdk/client-dynamodb'
22
import { models } from '@hello.nrfcloud.com/proto-map'
33
import chalk from 'chalk'
4-
import { publicDevicesRepo } from '../../sharing/publicDevicesRepo.js'
4+
import { publicDevicesRepo } from '../../devices/publicDevicesRepo.js'
55
import type { CommandDefinition } from './CommandDefinition.js'
66

77
const modelIDs = Object.keys(models)
88

99
export const shareDevice = ({
1010
db,
1111
publicDevicesTableName,
12+
idIndex,
1213
}: {
1314
db: DynamoDBClient
1415
publicDevicesTableName: string
16+
idIndex: string
1517
}): CommandDefinition => ({
1618
command: `share-device <deviceId> <model> <email>`,
1719
action: async (deviceId, model, email) => {
@@ -27,6 +29,7 @@ export const shareDevice = ({
2729
const publicDevice = publicDevicesRepo({
2830
db,
2931
TableName: publicDevicesTableName,
32+
idIndex,
3033
})
3134
const maybePublished = await publicDevice.share({
3235
deviceId,
File renamed without changes.

0 commit comments

Comments
 (0)