diff --git a/docs/00-initial-setup/README.md b/docs/00-initial-setup/README.md index fd87a951..5ab1e229 100644 --- a/docs/00-initial-setup/README.md +++ b/docs/00-initial-setup/README.md @@ -92,6 +92,7 @@ If you are working in your own AWS account, follow the steps below to launch a C Region| Code | Launch ------|------|------- + AP Southeast (Sydney) | ap-southeast-2 | [![Launch setup resource in ap-southeast-2](images/cfn-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?stackName=Secure-Serverless&templateURL=https://s3.amazonaws.com/wildrydes-us-east-1/Security/init-template.yml) EU (Ireland) | eu-west-1 | [![Launch setup resource in eu-west-1](images/cfn-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=Secure-Serverless&templateURL=https://s3.amazonaws.com/wildrydes-us-east-1/Security/init-template.yml) US West (Oregon) | us-west-2 | [![Launch setup resource in us-west-2](images/cfn-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?stackName=Secure-Serverless&templateURL=https://s3.amazonaws.com/wildrydes-us-east-1/Security/init-template.yml) US East (N. Virginia) | us-east-1 | [![Launch setup resource in us-east-1](images/cfn-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=Secure-Serverless&templateURL=https://s3.amazonaws.com/wildrydes-us-east-1/Security/init-template.yml) @@ -381,11 +382,18 @@ In addition to the lambda code, the configurations for Lambda function and the R After doing this, it's time to test your API locally using SAM Local. -1. On the **right panel**, click on **AWS Resources**. +1. On the **top right**, click on the cog. + +1. In the **Preferences Menu**, open **AWS settings** + + +1. Untoggle the AWS Toolkit + +1. On the **right panel**, click on **AWS Resources**. -1. You should see a folder tree with the name *Local Functions (1)*. +1. You should now see a folder tree with the name *Local Functions (1)*. 1. Select **UnicornPartsFunction** under the `src` folder 1. Once you have selected the function, click on the dropdown on the panel on the top, and select **Run APIGateway Local** diff --git a/docs/00-initial-setup/images/0D-aws-preferences.png b/docs/00-initial-setup/images/0D-aws-preferences.png new file mode 100755 index 00000000..a009e9ed Binary files /dev/null and b/docs/00-initial-setup/images/0D-aws-preferences.png differ diff --git a/docs/00-initial-setup/images/0D-aws-settings.png b/docs/00-initial-setup/images/0D-aws-settings.png new file mode 100755 index 00000000..7d435c39 Binary files /dev/null and b/docs/00-initial-setup/images/0D-aws-settings.png differ diff --git a/docs/00-initial-setup/images/0D-aws-toolkit.png b/docs/00-initial-setup/images/0D-aws-toolkit.png new file mode 100755 index 00000000..916be38f Binary files /dev/null and b/docs/00-initial-setup/images/0D-aws-toolkit.png differ diff --git a/docs/01-add-authentication/README.md b/docs/01-add-authentication/README.md index ca65255c..0611b4ea 100644 --- a/docs/01-add-authentication/README.md +++ b/docs/01-add-authentication/README.md @@ -347,10 +347,9 @@ Now we have configured our API so only authenticated requests can get through to To make authenticated requests using the admin client credentials we just created in Module 1C, we can use PostMan: -1. In Postman, right click on the **Manage Partner** folder and click **edit** -1. In the Edit Folder window that pops up, go to **Authorization** tab, and change the Auth **Type** to `OAuth 2.0`, then click **Get New Access Token** - - ![postman add auth](images/1E-postman-add-auth.png) +1. In Postman, left click on the **Manage Partner** folder +1. In the **Authorization** tab, and change the Auth **Type** to `OAuth 2.0`, then click **Get New Access Token** + ![postman add auth](images/1E-postman-gettoken.png) 1. Configure the token request: @@ -365,8 +364,6 @@ To make authenticated requests using the admin client credentials we just create * **Client Secret**: this the client secret of the admin we created in Module 1D * **Scope**: it's optional (the token will be scoped anyways) we can leave it blank - ![postman add auth](images/1E-postman-gettoken.png) - And click **Request Token** 1. Now you should see the new token returned from Cognito. scroll down and click **Use Token** diff --git a/docs/01-add-authentication/images/1E-postman-add-auth.png b/docs/01-add-authentication/images/1E-postman-add-auth.png deleted file mode 100644 index 499c76e6..00000000 Binary files a/docs/01-add-authentication/images/1E-postman-add-auth.png and /dev/null differ diff --git a/docs/01-add-authentication/images/1E-postman-gettoken.png b/docs/01-add-authentication/images/1E-postman-gettoken.png old mode 100644 new mode 100755 index ad45ead7..3d156f6d Binary files a/docs/01-add-authentication/images/1E-postman-gettoken.png and b/docs/01-add-authentication/images/1E-postman-gettoken.png differ diff --git a/docs/06-waf/README.md b/docs/06-waf/README.md index 3f23018d..944bf6f8 100644 --- a/docs/06-waf/README.md +++ b/docs/06-waf/README.md @@ -68,19 +68,16 @@ If you have completed **Module 3: Input validation on API Gateway**, your API no -### Module 6A: Create a WAF ACL +### Module 6A: Describe a Web ACL Now let's start creating an AWS WAF to give us additional protection: 1. Go to the [AWS WAF Console](https://console.aws.amazon.com/wafv2/home#/wafhome) -1. The AWS WAF console has recently released a new version: see [Introducing AWS Managed Rules for AWS WAF -](https://aws.amazon.com/about-aws/whats-new/2019/11/introducing-aws-managed-rules-for-aws-waf/). However, this workshop has not been yet adapted to the new version. Therefore, we will be using the classic version of the WAF console. You can use the **Switch to AWS WAF Classic** button to switch to classic: - ![](images/switch-waf-classic.png) - -1. Click on **Create web ACL** on the WAF Classic console +1. Click on **Create web ACL** + ![](images/6A-create-web-acl.png) ![](images/classifc-waf-opening.png) 1. In Step 1 of the ACL creation wizard, fill in: @@ -88,122 +85,66 @@ Now let's start creating an AWS WAF to give us additional protection: * **Web ACL Name**: `ProtectUnicorn` * **CloudWatch metric name**: this should be automatically populated for you * **Region**: select the AWS region you chose for previous steps of the workshop - * **Resource type to associate with web ACL**: Pick `API Gateway` - * **Amazon API Gateway API**: Pick the API Gateway we deployed previously, `CustomizeUnicorns` - * **Stage**: select `dev` - - ![screenshot](images/web-acl-name.png) - - and click **Next** -### Module 6B: Create WAF conditions +1. To associate the WAF with your API Gateway resources, click **add AWS resources** and select the API Gateway we deployed previously, `CustomizeUnicorns` + ![screenshot](images/6A-associate-resources.png) + click **Add** + ![screenshot](images/6A-web-acl-step-1.png) + and then **Next** -1. Next you will create 2 different conditions. Let's start with a condition to restrict the maximum size of request body: - * Go to **Size constraint conditions** section, click **Create condition** - * Give the condition a name, like `LargeBodyMatch` - * In Filter settings, add a filer on - * **Part of the request to filter on**: body - * **Comparison operator**: Greater than - * **Size (Bytes)**: 3000 - * Click **Add filter** - * After the filter is added to the condition, click **Create** +### Module 6B: Add web ACL rules - ![screenshot](images/large-body-condition.png) - +1. Next you will create 3 different rules. Let's start with a rule to restrict the maximum size of request body: -1. Next, let's add a SQL injection condition. - - * Go to **SQL injection match conditions** section, click **Create condition** - * Give the condition a name, like `SQLinjectionMatch` - * Here, we want to add multiple rules to inspect multiple aspects of the request: request body, request URI and query strings - * In the **Filter settings**, add 4 filters: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Part of the request to filter onTransformation
1BodyNone
2BodyURL decode
3URIURL decode
4Query stringURL decode
- * Click **Create** + ![screenshot](images/6B-own-rule.png) + * **Rule Type** select **Rule Builder** + * **Rule Name** Give the rulle a name, like `LargeBodyMatch` + * **Type** Regular rule + * **If a request** matches the statement + * **Inspect** Body + * **Content Type** Plain text + * **Match type** Size greater than + * **Size** `3000` + * **Action** Block + ![screenshot](images/6B-large-body-rule.png) + * Then click **Add Rule** - ![screenshot](images/sql-condition.png) - -1. Click **Next** to advance to the **Create rules** page - - -### Module 6C: Create WAF rules +1. Next, let's add a SQL injection rule. -1. Next, we create **Rules** that are composed of one or more **Conditions**. Let's start by creating a rule based on the request body size condition: - - * Click **Create Rule** - * Give it a name, like `LargeBodyMatchRule` - * For **Rule type**, keep `Regular rule` - * In Add conditions section, select - * `does` - * `match at least one of the filters in the size constraint condition ` - * `LargeBodyMatch` -- the name of the condition we created for large request body in 6B - - * Then click **Create** + ![screenshot](images/6B-managed-rule.png) + * Expand the **AWS managed rule groups** section + * toggle the **SQL database** option + ![screenshot](images/6B-sql-managed-rule.png) + * Then click **Add Rule** - ![screenshot](images/large-body-rule.png) - -1. Next, we create the rule for SQL injection. - - * Click **Create Rule** - * Give it a name, like `SQLinjectionRule` - * For **Rule type**, keep `Regular rule` - * In Add conditions section, select - * `does` - * `match at least one of the filters in the SQL injection match condition ` - * `SQlInjectionMatch` -- the name of the condition we created for SQL injection in 6B - * Then click **Create** - - ![screenshot](images/sql-rule.png) 1. Lastly, we can create a rate-based rule that prevents an overwhelming number of requests (either valid or invalid) from flooding our API: - * Click **Create Rule** - * Give it a name, like `RequestFloodRule` + ![screenshot](images/6B-own-rule.png) + * Give it a **Name**, like `RequestFloodRule` * For **Rule type**, select `Rate-based rule` * For **Rate limit**, use `2000` + * **IP address to use for rate limiting** Source IP address + * **Criteria to count request towards rate limit** Consider all requests + * **Action** Block * Then click **Create** - ![screenshot](images/request-flood-rule.png) + ![screenshot](images/6B-request-flood-rule.png) 1. You should now see 3 rules in like below. Ensure you select `Block` if the request matches any of the rules. For **Default action**, select `Allow all requests that don't match any rules` - ![screenshot](images/list-rules.png) - -1. Click **Review and create** + ![screenshot](images/6B-three-rules.png) + ### Modules 6C: Rule priorities, metrics and review +1. Frome here you can use the default selected options, + + ![screenshot](images/6B-rule-priorities.png) -1. In the next page, review the configuration and click **Confirm and Create** - - ![screenshot](images/review-acl.png) + ![screenshot](images/6B-metrics.png) +1. and now you can **Create Web ACL** You have now added a WAF to our API gateway stage! diff --git a/docs/06-waf/images/6A-associate-resources.png b/docs/06-waf/images/6A-associate-resources.png new file mode 100755 index 00000000..287f06ad Binary files /dev/null and b/docs/06-waf/images/6A-associate-resources.png differ diff --git a/docs/06-waf/images/6A-create-web-acl.png b/docs/06-waf/images/6A-create-web-acl.png new file mode 100755 index 00000000..95cd9c3f Binary files /dev/null and b/docs/06-waf/images/6A-create-web-acl.png differ diff --git a/docs/06-waf/images/6A-web-acl-step-1.png b/docs/06-waf/images/6A-web-acl-step-1.png new file mode 100755 index 00000000..adeb9a6c Binary files /dev/null and b/docs/06-waf/images/6A-web-acl-step-1.png differ diff --git a/docs/06-waf/images/6B-large-body-rule.png b/docs/06-waf/images/6B-large-body-rule.png new file mode 100755 index 00000000..21265a80 Binary files /dev/null and b/docs/06-waf/images/6B-large-body-rule.png differ diff --git a/docs/06-waf/images/6B-managed-rule.png b/docs/06-waf/images/6B-managed-rule.png new file mode 100755 index 00000000..62c43dea Binary files /dev/null and b/docs/06-waf/images/6B-managed-rule.png differ diff --git a/docs/06-waf/images/6B-metrics.png b/docs/06-waf/images/6B-metrics.png new file mode 100755 index 00000000..2a4cfd04 Binary files /dev/null and b/docs/06-waf/images/6B-metrics.png differ diff --git a/docs/06-waf/images/6B-own-rule.png b/docs/06-waf/images/6B-own-rule.png new file mode 100755 index 00000000..75d20704 Binary files /dev/null and b/docs/06-waf/images/6B-own-rule.png differ diff --git a/docs/06-waf/images/6B-request-flood-rule.png b/docs/06-waf/images/6B-request-flood-rule.png new file mode 100755 index 00000000..b773400c Binary files /dev/null and b/docs/06-waf/images/6B-request-flood-rule.png differ diff --git a/docs/06-waf/images/6B-rule-priorities.png b/docs/06-waf/images/6B-rule-priorities.png new file mode 100755 index 00000000..524395b8 Binary files /dev/null and b/docs/06-waf/images/6B-rule-priorities.png differ diff --git a/docs/06-waf/images/6B-sql-managed-rule.png b/docs/06-waf/images/6B-sql-managed-rule.png new file mode 100755 index 00000000..49885b9d Binary files /dev/null and b/docs/06-waf/images/6B-sql-managed-rule.png differ diff --git a/docs/06-waf/images/6B-three-rules.png b/docs/06-waf/images/6B-three-rules.png new file mode 100755 index 00000000..b4dd215b Binary files /dev/null and b/docs/06-waf/images/6B-three-rules.png differ diff --git a/docs/06-waf/images/large-body-condition.png b/docs/06-waf/images/large-body-condition.png deleted file mode 100644 index 65be84c2..00000000 Binary files a/docs/06-waf/images/large-body-condition.png and /dev/null differ diff --git a/docs/06-waf/images/large-body-rule.png b/docs/06-waf/images/large-body-rule.png deleted file mode 100644 index a144b6ad..00000000 Binary files a/docs/06-waf/images/large-body-rule.png and /dev/null differ diff --git a/docs/06-waf/images/list-rules.png b/docs/06-waf/images/list-rules.png deleted file mode 100644 index dd1f9ac6..00000000 Binary files a/docs/06-waf/images/list-rules.png and /dev/null differ diff --git a/docs/06-waf/images/request-flood-rule.png b/docs/06-waf/images/request-flood-rule.png deleted file mode 100644 index 6db45565..00000000 Binary files a/docs/06-waf/images/request-flood-rule.png and /dev/null differ diff --git a/docs/06-waf/images/review-acl.png b/docs/06-waf/images/review-acl.png deleted file mode 100644 index d4949d75..00000000 Binary files a/docs/06-waf/images/review-acl.png and /dev/null differ diff --git a/docs/06-waf/images/sql-condition.png b/docs/06-waf/images/sql-condition.png deleted file mode 100644 index 19d36f8f..00000000 Binary files a/docs/06-waf/images/sql-condition.png and /dev/null differ diff --git a/docs/06-waf/images/sql-rule.png b/docs/06-waf/images/sql-rule.png deleted file mode 100644 index 4d1c761c..00000000 Binary files a/docs/06-waf/images/sql-rule.png and /dev/null differ diff --git a/docs/06-waf/images/switch-waf-classic.png b/docs/06-waf/images/switch-waf-classic.png deleted file mode 100644 index 0abfcdbd..00000000 Binary files a/docs/06-waf/images/switch-waf-classic.png and /dev/null differ diff --git a/docs/06-waf/images/web-acl-name.png b/docs/06-waf/images/web-acl-name.png deleted file mode 100644 index a64630c7..00000000 Binary files a/docs/06-waf/images/web-acl-name.png and /dev/null differ