Skip to content

Commit 637fc6a

Browse files
authored
fix(iam): roleName not validated in fromRoleName function (#24549)
The `validateRoleName` function validates the `roleName` parameter passed to the `fromRoleName` function following the pattern specified in the [docs](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html). Closes #24503. **Note** I added the `IAM_IMPORTED_ROLE_STACK_SAFE_DEFAULT_POLICY_NAME` feature flag check because [this](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-iam/test/integ.imported-role.ts) integration test failed, generating a `roleName` in the format `${Token[TOKEN.26]}`. I don't know if this is the expected behavior, a bug, or an error in my implementation. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 552cef4 commit 637fc6a

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

packages/@aws-cdk/aws-iam/lib/role.ts

+13
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ export class Role extends Resource implements IRole {
318318
* @param options allow customizing the behavior of the returned role
319319
*/
320320
public static fromRoleName(scope: Construct, id: string, roleName: string, options: FromRoleNameOptions = {}) {
321+
// Validate the role name only if not a token
322+
if (!Token.isUnresolved(roleName)) {
323+
this.validateRoleName(roleName);
324+
}
321325
return Role.fromRoleArn(scope, id, Stack.of(scope).formatArn({
322326
region: '',
323327
service: 'iam',
@@ -367,6 +371,15 @@ export class Role extends Resource implements IRole {
367371
});
368372
}
369373

374+
private static validateRoleName(roleName: string) {
375+
// https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html
376+
const regexp: RegExp = /[\w+=,.@-]+/;
377+
const matches = regexp.exec(roleName);
378+
if (!(matches && matches.length === 1 && matches[0] === roleName)) {
379+
throw new Error(`The role name ${roleName} does not match the IAM conventions.`);
380+
}
381+
}
382+
370383
public readonly grantPrincipal: IPrincipal = this;
371384
public readonly principalAccount: string | undefined = this.env.account;
372385

packages/@aws-cdk/aws-iam/test/role.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -1294,3 +1294,14 @@ test('cross-env role ARNs include path', () => {
12941294
},
12951295
});
12961296
});
1297+
1298+
test('fromRoleName should validate role name (only if not a token)', () => {
1299+
const app = new App();
1300+
const stack = new Stack(app, 'MyStack');
1301+
expect(() => {
1302+
Role.fromRoleName(stack, 'Invalid role name', 'arn:aws:iam::***:role/myrole');
1303+
}).toThrow(/does not match the IAM conventions/);
1304+
expect(() => {
1305+
Role.fromRoleName(stack, 'Token', '${Token[TOKEN.26]}');
1306+
}).not.toThrow();
1307+
});

0 commit comments

Comments
 (0)