Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(iam): missing validation for actions added post instantiation of a policy statement #21906

Merged
merged 7 commits into from
Oct 14, 2022

Conversation

VarunWachaspati
Copy link
Contributor

Bug Description

The validation for actions/nonActions currently only exists in the constructor of the PolicyStatement class as shown below -

constructor(props: PolicyStatementProps = {}) {
// Validate actions
for (const action of [...props.actions || [], ...props.notActions || []]) {
if (!/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action) && !cdk.Token.isUnresolved(action)) {
throw new Error(`Action '${action}' is invalid. An action string consists of a service namespace, a colon, and the name of an action. Action names can include wildcards.`);
}
}

The above validation is missing when we add an action/nonAction post instantiation of the IAM policy statement leading to discrepancy in the behaviour.
The following snippet doesn't throw any error -

const statement = new iam.PolicyStatement({ resources: ['*'] });
statement.addActions('action');
statement.addNonActions('nonaction');

Solution

  • Refactored the validation in the constructor into a separate private method called validatePolicyActions()
  • Executing this new validation method in the addActions() and addNonActions()
  • Fixed existing unit tests which assumed the above behaviour

fixes #21821


All Submissions:

Adding new Unconventional Dependencies:

  • This PR adds new unconventional dependencies following the process described here

New Features

  • Have you added the new feature to an integration test?
    • Did you use yarn integ to deploy the infrastructure and generate the snapshot (i.e. yarn integ without --dry-run)?

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@gitpod-io
Copy link

gitpod-io bot commented Sep 3, 2022

@github-actions github-actions bot added bug This issue is a bug. effort/small Small work item – less than a day of effort p2 labels Sep 3, 2022
@aws-cdk-automation aws-cdk-automation requested a review from a team September 3, 2022 11:21
@VarunWachaspati
Copy link
Contributor Author

VarunWachaspati commented Sep 3, 2022

Need some guidance in fixing the following failing unit test.

test('addResources() will not break a list-encoded Token', () => {
const stack = new Stack();
const statement = new PolicyStatement();
statement.addActions(...Lazy.list({ produce: () => ['service:a', 'service:b', 'service:c'] }));
statement.addResources(...Lazy.list({ produce: () => ['x', 'y', 'z'] }));
expect(stack.resolve(statement.toStatementJson())).toEqual({
Effect: 'Allow',
Action: ['service:a', 'service:b', 'service:c'],
Resource: ['x', 'y', 'z'],
});
});

As per my understanding, Lazy.list(...) token should evaluate to true when passed to cdk.Token.isUnresolved(), but for some unknown reason it is evaluating to false instead and throwing an error as per the below logic.

if (!cdk.Token.isUnresolved(action) && !/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action)) {
throw new Error(`Action '${action}' is invalid. An action string consists of a service namespace, a colon, and the name of an action. Action names can include wildcards.`);

Thus causing the above unit test to fail.

Is this is a bug Token.isUnresolved() method by any chance?

@TheRealAmazonKendra
Copy link
Contributor

Need some guidance in fixing the following failing unit test.

test('addResources() will not break a list-encoded Token', () => {
const stack = new Stack();
const statement = new PolicyStatement();
statement.addActions(...Lazy.list({ produce: () => ['service:a', 'service:b', 'service:c'] }));
statement.addResources(...Lazy.list({ produce: () => ['x', 'y', 'z'] }));
expect(stack.resolve(statement.toStatementJson())).toEqual({
Effect: 'Allow',
Action: ['service:a', 'service:b', 'service:c'],
Resource: ['x', 'y', 'z'],
});
});

As per my understanding, Lazy.list(...) token should evaluate to true when passed to cdk.Token.isUnresolved(), but for some unknown reason it is evaluating to false instead and throwing an error as per the below logic.

if (!cdk.Token.isUnresolved(action) && !/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action)) {
throw new Error(`Action '${action}' is invalid. An action string consists of a service namespace, a colon, and the name of an action. Action names can include wildcards.`);

Thus causing the above unit test to fail.
Is this is a bug Token.isUnresolved() method by any chance?

You don't seem to have any tokens in

Need some guidance in fixing the following failing unit test.

test('addResources() will not break a list-encoded Token', () => {
const stack = new Stack();
const statement = new PolicyStatement();
statement.addActions(...Lazy.list({ produce: () => ['service:a', 'service:b', 'service:c'] }));
statement.addResources(...Lazy.list({ produce: () => ['x', 'y', 'z'] }));
expect(stack.resolve(statement.toStatementJson())).toEqual({
Effect: 'Allow',
Action: ['service:a', 'service:b', 'service:c'],
Resource: ['x', 'y', 'z'],
});
});

As per my understanding, Lazy.list(...) token should evaluate to true when passed to cdk.Token.isUnresolved(), but for some unknown reason it is evaluating to false instead and throwing an error as per the below logic.

if (!cdk.Token.isUnresolved(action) && !/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action)) {
throw new Error(`Action '${action}' is invalid. An action string consists of a service namespace, a colon, and the name of an action. Action names can include wildcards.`);

Thus causing the above unit test to fail.
Is this is a bug Token.isUnresolved() method by any chance?

You've created a token list but then are evaluating each individual token as a string. The formatting for list vs string are different.

@VarunWachaspati
Copy link
Contributor Author

Thank you so much @TheRealAmazonKendra for helping out.
I have updated the PR accordingly now and all existing tests are passing.
Since this was primarily a refactor, I didn't add any additional tests. But if anything else is required please let me know.

@TheRealAmazonKendra
Copy link
Contributor

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Sep 13, 2022

update

✅ Branch has been successfully updated

@VarunWachaspati
Copy link
Contributor Author

Hi @TheRealAmazonKendra
Can we merge this PR?
If not, please let me know the next steps.

@VarunWachaspati
Copy link
Contributor Author

Bumping up for visibility.

@TheRealAmazonKendra
Copy link
Contributor

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Oct 2, 2022

update

✅ Branch has been successfully updated

Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Pull Request Linter fails with the following errors:

❌ Fixes must contain a change to an integration test file and the resulting snapshot.

PRs must pass status checks before we can provide a meaningful review.

Copy link
Contributor

@TheRealAmazonKendra TheRealAmazonKendra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that your PR title confirms to the conventional commit standard (fix, feat, chore) and that it is written in a style that will reflect correctly in the change log (See Contributing Guide, Pull Requests).

Additionally, we need test cases for failure cases. The tests in this PR only covers success cases.

@VarunWachaspati VarunWachaspati changed the title fix(iam): validation while adding statement policy actions/nonactions post instantiation fix(iam): missing validation for actions added post instantiation of a policy statement Oct 9, 2022
@VarunWachaspati
Copy link
Contributor Author

Sorry for the delay.

  • Changed the title of the PR to the best of my knowledge to reflect the nature of the bug being fixed, if it doesn't cut it please do let me know.
  • Added a failure unit test case asserting that we throw an error whenever an invalid action is being added to the policy statement post instantiation it throws an error.
  • Can you please guide me in adding an integration test for this change? I wasn't able to figure it out.

@Naumel
Copy link
Contributor

Naumel commented Oct 10, 2022

(...)
* Can you please guide me in adding an integration test for this change? I wasn't able to figure it out.

Hello, have you looked at https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md already?

@Naumel Naumel added the @aws-cdk/aws-iam Related to AWS Identity and Access Management label Oct 10, 2022
@VarunWachaspati
Copy link
Contributor Author

Yes, I did. I was confused regarding what kind of integration should I be adding in this case, since this PR fixes a validation check that was previously missed. I have added unit tests to assert the validation.

@TheRealAmazonKendra TheRealAmazonKendra added the pr-linter/exempt-integ-test The PR linter will not require integ test changes label Oct 13, 2022
@aws-cdk-automation aws-cdk-automation dismissed their stale review October 13, 2022 23:31

✅ Updated pull request passes all PRLinter validations. Dissmissing previous PRLinter review.

@mergify
Copy link
Contributor

mergify bot commented Oct 13, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 9b47ba5
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit 10974d9 into aws:main Oct 14, 2022
@mergify
Copy link
Contributor

mergify bot commented Oct 14, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

mrgrain pushed a commit to mrgrain/aws-cdk that referenced this pull request Oct 24, 2022
…a policy statement (aws#21906)

## Bug Description
The validation for actions/nonActions currently only exists in the constructor of the PolicyStatement class as shown below - 
https://github.com/aws/aws-cdk/blob/56ba2ab2c2d9240b76ece17c3296488a63f0b232/packages/%40aws-cdk/aws-iam/lib/policy-statement.ts#L88-L95

The above validation is missing when we add an action/nonAction post instantiation of the IAM policy statement leading to discrepancy in the behaviour.
The following snippet doesn't throw any error - 
```typescript
const statement = new iam.PolicyStatement({ resources: ['*'] });
statement.addActions('action');
statement.addNonActions('nonaction');
```
## Solution
- Refactored the validation in the constructor into a separate private method called `validatePolicyActions()`
- Executing this new validation method in the `addActions()` and `addNonActions()`
- Fixed existing unit tests which assumed the above behaviour

fixes aws#21821

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management bug This issue is a bug. effort/small Small work item – less than a day of effort p2 pr-linter/exempt-integ-test The PR linter will not require integ test changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(iam): policy statement action is not validated if added post instantiation
4 participants