Skip to content

Commit 9a4e165

Browse files
committed
fix(iam): throw error when statement id is invalid (#34819)
Resolves #34819 by throwing error when PolicyStatement Statement id contains characters not allowed by the API. See docs in https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html
1 parent 1965014 commit 9a4e165

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

packages/aws-cdk-lib/aws-iam/lib/policy-statement.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export class PolicyStatement {
9292

9393
constructor(props: PolicyStatementProps = {}) {
9494
this._sid = props.sid;
95+
this.validateStatementId(this._sid);
9596
this._effect = props.effect || Effect.ALLOW;
9697

9798
this.addActions(...props.actions || []);
@@ -117,6 +118,7 @@ export class PolicyStatement {
117118
*/
118119
public set sid(sid: string | undefined) {
119120
this.assertNotFrozen('sid');
121+
this.validateStatementId(sid);
120122
this._sid = sid;
121123
}
122124

@@ -232,6 +234,12 @@ export class PolicyStatement {
232234
}
233235
}
234236

237+
private validateStatementId(sid?: string) {
238+
if (sid !== undefined && !cdk.Token.isUnresolved(sid) && !/^[0-9A-Za-z]*$/.test(sid)) {
239+
throw new UnscopedValidationError(`Statement ID (sid) must be alphanumeric. Got '${sid}'. The Sid element supports ASCII uppercase letters (A-Z), lowercase letters (a-z), and numbers (0-9).`);
240+
}
241+
}
242+
235243
private validatePolicyActions(actions: string[]) {
236244
// In case of an unresolved list of actions return early
237245
if (cdk.Token.isUnresolved(actions)) return;

packages/aws-cdk-lib/aws-iam/test/policy-statement.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,28 @@ describe('IAM policy statement', () => {
260260
expect(mod).toThrow(/can no longer be modified/);
261261
}
262262
});
263+
264+
test('accepts valid alphanumeric sid', () => {
265+
const validSids = ['ValidSid123', 'ALLCAPS', '123456', 'abc123DEF'];
266+
267+
for (const sid of validSids) {
268+
expect(() => new PolicyStatement({ sid })).not.toThrow();
269+
}
270+
});
271+
272+
test('throws error when sid contains non-alphanumeric characters', () => {
273+
const invalidSids = ['invalid-sid', 'with space', 'with_underscore', 'with.dot', 'with!special@chars'];
274+
275+
for (const sid of invalidSids) {
276+
expect(() => new PolicyStatement({ sid }))
277+
.toThrow(`Statement ID (sid) must be alphanumeric. Got '${sid}'. The Sid element supports ASCII uppercase letters (A-Z), lowercase letters (a-z), and numbers (0-9).`);
278+
}
279+
});
280+
281+
test('throws error when setting sid to non-alphanumeric value', () => {
282+
const statement = new PolicyStatement();
283+
284+
expect(() => statement.sid = 'invalid-sid')
285+
.toThrow('Statement ID (sid) must be alphanumeric. Got \'invalid-sid\'. The Sid element supports ASCII uppercase letters (A-Z), lowercase letters (a-z), and numbers (0-9).');
286+
});
263287
});

0 commit comments

Comments
 (0)