From e8e7e3a30fce71dfbad3fc31efb607fb1b3a5180 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:36:11 -0700 Subject: [PATCH 01/17] Update 3-ssdlc.livemd Updates to the Rate Limiting Section In ESCT: Part 3 - Secure SDLC Concepts Elixir Sec Coding Training - Improve Rate-Limiting Lesson (issue #24) --- modules/3-ssdlc.livemd | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 5ce692b..4fed24d 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -57,7 +57,23 @@ Additionally, thought can be put into how you architect data flows with regards ### Description -Rate limiting restricts the number of requests that can be allowed in a certain time frame on a specific resource. Rate limiting can be implemented to protect against a variety of attacks or abuses: +While performing their designed operations, applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Modern applications have a lot of things happening. + +When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal and external resources involved in the context of the application. This will help ensure the continued availablilty of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. + +When resources are not well managed, applications become vulnerable to negative impacts in performance, unintentional service failures, and denial of service attacks, in which a malicious actor takes advantage of resource limitations to intentionally overwhelm and crash a system. + +Implementing rate limiting is one security best practice that can help mitigate the ability of unlimited, undefined, or uncontrolled application input, to intentionally or inadvertently exahaust vital resources across all levels of application's context. + +### Implementation Approaches +There are multiple approaches to implementing rate limiting within an application and in general the approach is based on at least one of the following problematic scenarios: + +* Malicious actor-generated abusive traffic designed to force the application into a compromised state +* Malicious or legitimate users perform large load activites that requires significant processing power +* Malicious or legitimate users sending large number of queries, often repeatedly to the service +* Malicious or legitimate users sending large number of queries in a narrow timeframe + +Rate limiting can be implemented to protect against a variety of attacks or abuses: * Preventing Denial Of Service attacks (limiting the number of calls to expensive endpoints) * Limiting brute force attempts (such as on one time codes and passwords) @@ -65,6 +81,16 @@ Rate limiting restricts the number of requests that can be allowed in a certain ### Prevention +Per OWASP, consider limits on the following (please see Rate Limiting References below): + +* Execution timeouts +* Max allocable memory +* Number of file descriptors +* Number of processes +* Request payload size (e.g., uploads) +* Number of requests per client/resource +* Number of records per page to return in a single request response + When rate limiting a new action, begin by asking these questions: * "What are the maximum number of calls to my action that a reasonable non-malicious user would feasibly make in a given time period?" @@ -75,6 +101,10 @@ If the answer to one or more of those questions is yes, consider putting a limit More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. +### Rate Limiting References +(https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting) +(https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md) + ## Principle of Least Privilege Sometimes known as the Principle of Minimal Privilege or the Principle of Least Authority, the Principle of Least Privilege (PoLP) means that every entity* is only strictly given the essential privileges needed to perform its requirement. From 2259d06885f8f06b915939d6195d276d47b8441b Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 1 Feb 2023 10:12:44 -0700 Subject: [PATCH 02/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 4fed24d..342d6b2 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -57,7 +57,7 @@ Additionally, thought can be put into how you architect data flows with regards ### Description -While performing their designed operations, applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Modern applications have a lot of things happening. +While performing their designed operations; applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Simply put - modern applications have a lot of things happening! When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal and external resources involved in the context of the application. This will help ensure the continued availablilty of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. From 37aeb6991e2f4ac556fe7ebf780906b999ef5ac8 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 1 Feb 2023 10:16:24 -0700 Subject: [PATCH 03/17] Update 3-ssdlc.livemd --- modules/3-ssdlc.livemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 342d6b2..49b7560 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -57,7 +57,7 @@ Additionally, thought can be put into how you architect data flows with regards ### Description -While performing their designed operations; applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Simply put - modern applications have a lot of things happening! +While performing their designed operations, applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Simply put - modern applications have a lot of things happening! When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal and external resources involved in the context of the application. This will help ensure the continued availablilty of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. @@ -69,7 +69,7 @@ Implementing rate limiting is one security best practice that can help mitigate There are multiple approaches to implementing rate limiting within an application and in general the approach is based on at least one of the following problematic scenarios: * Malicious actor-generated abusive traffic designed to force the application into a compromised state -* Malicious or legitimate users perform large load activites that requires significant processing power +* Malicious or legitimate users perform large load activities that requires significant processing power * Malicious or legitimate users sending large number of queries, often repeatedly to the service * Malicious or legitimate users sending large number of queries in a narrow timeframe From 023393ec5cdf52b09ad9632cd69270486c1470df Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 3 Feb 2023 15:03:13 -0700 Subject: [PATCH 04/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 49b7560..85921e4 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -102,8 +102,8 @@ If the answer to one or more of those questions is yes, consider putting a limit More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. ### Rate Limiting References -(https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting) -(https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md) +1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting +2. https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md ## Principle of Least Privilege From 675d4fee6439e48291265c65e58d1c040501ce78 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 3 Feb 2023 15:03:39 -0700 Subject: [PATCH 05/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 85921e4..fc83788 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -59,7 +59,7 @@ Additionally, thought can be put into how you architect data flows with regards While performing their designed operations, applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Simply put - modern applications have a lot of things happening! -When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal and external resources involved in the context of the application. This will help ensure the continued availablilty of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. +When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal / external resources involved in the context of the application. This will help ensure the continued availability of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. When resources are not well managed, applications become vulnerable to negative impacts in performance, unintentional service failures, and denial of service attacks, in which a malicious actor takes advantage of resource limitations to intentionally overwhelm and crash a system. From d62c69572a98ccd5babe4e9dbd13ed1bd8abce95 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Thu, 9 Feb 2023 13:33:11 -0700 Subject: [PATCH 06/17] Update 3-ssdlc.livemd --- modules/3-ssdlc.livemd | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index fc83788..69f3a4d 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -101,6 +101,34 @@ If the answer to one or more of those questions is yes, consider putting a limit More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. +Two approaches to rate limiting +-Application Level... +-Network level... + + +### Example / Quiz + + +The Elixir language has a built-in rate-limiter called Hammer (https://hexdocs.pm/hammer/frontpage.html). Some organizations chose to apply limits based on userId as in the example below. + +The check_rate function below takes 3 arguments: + +1. The first is what we've decided apply the limit to, in this case, the userID +2. The second, 60_000, represents the number of milliseconds in 1 minute (1000 milliseconds per 1 second, 60 seconds in 1 minute) +3. The last, 10, represents the number of times the userID can appear to have done a particular action before we stop them. In this case, 10 times. + +``` +# limit file uploads to x per minute per user +userId = getUserId() +case Hammer.check_rate("action:#{userId}", 60_000, 10) do + {:allow, _count} -> + # let them do it + {:deny, _limit} -> + # nope +end +``` + + ### Rate Limiting References 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting 2. https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md From b6413c33b3823e2ef4688f3e33392416496eb5fe Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 10 Feb 2023 12:29:47 -0700 Subject: [PATCH 07/17] Update 3-ssdlc.livemd --- modules/3-ssdlc.livemd | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 69f3a4d..a08d409 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -105,9 +105,11 @@ Two approaches to rate limiting -Application Level... -Network level... +### Application Level Rate Limiting - -### Example / Quiz +Rate limiting around Application Features and Functionality - For instance a single user who has access to your application and therefore certain features within the application that respond to user requests for specific actions for instance like uploading a file, sending messages, etc. While developing an application, it is important to implement limits around how much and what actions users can take and how often. +### Example The Elixir language has a built-in rate-limiter called Hammer (https://hexdocs.pm/hammer/frontpage.html). Some organizations chose to apply limits based on userId as in the example below. @@ -128,6 +130,29 @@ case Hammer.check_rate("action:#{userId}", 60_000, 10) do end ``` +### Network Level Rate Limiting - Network traffic -> Firewalls +Source IP address, destination for server hosting your service +Firewall, are traditionally a network device that filters traffic based on configured access control list that defines good traffic and depending on the firewall captures/analyzes network packets and blocks bad traffic. + +Firewall functionality implemented at the application level, Web Application Firewalls (WAF) operate similarly by specificly looking at Web traffic, over HTTP/HTTPS port 80 443 for malicious incoming from sources across the internet. + +### Example + +If your public facing URI/URL for your application is hxxps://yourapplication.org/login + +``` +The following is an example of requests that can come from across the internet targeting your application from the same source IP 123.123.123.123 for instance: +hxxps://yourelixirapplication.org/secret +hxxps://yourelixirapplication.org/admin +hxxps://yourelixirapplication.org/login?user=test +hxxps://yourelixirapplication.org/login?user=test&pass=test +..... + +``` +Your site will handle these incoming requests either by returning 404 responses, etc. Imagine receiving thousands of these requests, however, as can be generated by automated tools freely available to malicious users. If your server/service processing these request was not built/designed to anticipate this scenario, the server could crash. + +A WAF can be configured to limit the number of tries from the same IP address. In the above example, if the same IP is the source for more than 100 of these attempts within 5 seconds, the WAF can ensure those requests don't reach your application. + ### Rate Limiting References 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting From c6fe64d4a5dcdc08bacf14d09344aed99f9057b9 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 10 Feb 2023 14:27:32 -0700 Subject: [PATCH 08/17] Update 3-ssdlc.livemd Updates complete - ready for review --- modules/3-ssdlc.livemd | 103 ++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index a08d409..befdfb6 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -59,104 +59,113 @@ Additionally, thought can be put into how you architect data flows with regards While performing their designed operations, applications send traffic across networks, make client requests, generate server responses, and consume processing and memory capacity from the computing machines on which they are hosted. They often have components, like APIs that interact with data sources and services. Simply put - modern applications have a lot of things happening! -When building an application, it is necessary to consider approaches to manage the access and use of all relevant internal / external resources involved in the context of the application. This will help ensure the continued availability of the application and it's functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. +When building an application, it is necessary to consider approaches to manage the stress on all internal and external resources involved within the context of the application. This will help ensure the continued availability of the application and its functionality for all legitimate users and entities. This is particularly important for applications that run critical infrastructure and other key services organizations rely on for business operations. -When resources are not well managed, applications become vulnerable to negative impacts in performance, unintentional service failures, and denial of service attacks, in which a malicious actor takes advantage of resource limitations to intentionally overwhelm and crash a system. +When resources are not well managed, applications become vulnerable to negative impacts in performance, service outages, and denial of service attacks, in which a malicious actor takes advantage of resource limitations to intentionally overwhelm and crash a system. -Implementing rate limiting is one security best practice that can help mitigate the ability of unlimited, undefined, or uncontrolled application input, to intentionally or inadvertently exahaust vital resources across all levels of application's context. +Uncontrolled Resource Consumption is ranked 23rd on the list of most dangerous software weaknesses. (https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html). Implementing rate limiting is one security best practice that can help mitigate the likelihood of an application inadvertently or being deliberately triggered into consuming vital resources. ### Implementation Approaches -There are multiple approaches to implementing rate limiting within an application and in general the approach is based on at least one of the following problematic scenarios: +There are multiple approaches to implementing rate limiting within an application and in general the approach is based on anticipating at least one of the following problematic scenarios: -* Malicious actor-generated abusive traffic designed to force the application into a compromised state +* Malicious actor-generating abusive traffic designed to force the application into a compromised state * Malicious or legitimate users perform large load activities that requires significant processing power * Malicious or legitimate users sending large number of queries, often repeatedly to the service * Malicious or legitimate users sending large number of queries in a narrow timeframe -Rate limiting can be implemented to protect against a variety of attacks or abuses: +Rate limiting can be implemented to protect against a variety of attacks or abuses by: -* Preventing Denial Of Service attacks (limiting the number of calls to expensive endpoints) +* Preventing Denial Of Service attacks (limiting the number of calls to resource expensive endpoints) * Limiting brute force attempts (such as on one time codes and passwords) * Programmatic abuse of services -### Prevention +There are generally two approaches to rate limiting: that which occurs at the application level, and that which occurs at the network level. -Per OWASP, consider limits on the following (please see Rate Limiting References below): +### Application Level Rate Limiting -* Execution timeouts -* Max allocable memory -* Number of file descriptors -* Number of processes -* Request payload size (e.g., uploads) -* Number of requests per client/resource -* Number of records per page to return in a single request response +Application rate limiting involves limiting interactions with functionality within the application. While developing an application, it is important to implement constraints around how often users can perform certain actions. -When rate limiting a new action, begin by asking these questions: - -* "What are the maximum number of calls to my action that a reasonable non-malicious user would feasibly make in a given time period?" -* "Is calling this action an expensive operation? If yes, how many calls in a minute would be enough to overburden the service?" -* "Is this action a candidate for brute force attacks?" (E.g. passwords, authentication tokens, one time passcodes) - -If the answer to one or more of those questions is yes, consider putting a limit on the number of times that the action can be called. Good rate limiting keeps in mind legitimate use cases and does not block regular user functionality, but protects the service from malicious or burdensome behavior. - -More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. - -Two approaches to rate limiting --Application Level... --Network level... - -### Application Level Rate Limiting - - -Rate limiting around Application Features and Functionality - For instance a single user who has access to your application and therefore certain features within the application that respond to user requests for specific actions for instance like uploading a file, sending messages, etc. While developing an application, it is important to implement limits around how much and what actions users can take and how often. +For instance, an application that allows users to submit documents will want to limit file size and the number of repeated upload attempts. Users who upload gigantic files or who try to send too many files back-to-back could case a crash. Implementing rate limiting around the file upload functionality will help ensure that components of the application that respond to unpredictable or intentionally malicious user input, will not exceed the application's server processing capacity or available storage space. ### Example -The Elixir language has a built-in rate-limiter called Hammer (https://hexdocs.pm/hammer/frontpage.html). Some organizations chose to apply limits based on userId as in the example below. +The Elixir language has a built-in rate-limiter called Hammer (https://hexdocs.pm/hammer/frontpage.html). Let's say there is an application that assigns users a userID and allows users to upload photos. Developers could decide to apply limits based on userId as in the example below. -The check_rate function below takes 3 arguments: +Note, the check_rate function below takes 3 arguments: -1. The first is what we've decided apply the limit to, in this case, the userID +1. The first is what we've decided apply the limit to, in this case, the userID. Each user has a unique userID. 2. The second, 60_000, represents the number of milliseconds in 1 minute (1000 milliseconds per 1 second, 60 seconds in 1 minute) -3. The last, 10, represents the number of times the userID can appear to have done a particular action before we stop them. In this case, 10 times. +3. The last, 5, represents the number of times the userID can appear to have done a particular action before we stop them. In this case, 5 times. +4. The user is able to upload 5 photos (action) within a given minute before being blocked or stopped. ``` # limit file uploads to x per minute per user userId = getUserId() -case Hammer.check_rate("action:#{userId}", 60_000, 10) do +case Hammer.check_rate("action:#{userId}", 60_000, 5) do {:allow, _count} -> # let them do it {:deny, _limit} -> - # nope + # nope too many end ``` -### Network Level Rate Limiting - Network traffic -> Firewalls -Source IP address, destination for server hosting your service -Firewall, are traditionally a network device that filters traffic based on configured access control list that defines good traffic and depending on the firewall captures/analyzes network packets and blocks bad traffic. +### Network Level Rate Limiting +Network level rate limiting involves limiting the internet traffic that is destined for the application's host, web server, or web services. In web applications, when a client makes a request for an application's resources by internet address, that request is made using the HTTP/HTTPS protocol across the internet and is then the service responds using an HTTP response status code indicating if the resource was successfully returned or if there has been an error, or other message as appropriate. + +At the network level, a firewall can be configured to sit between the internet and your application servers/services to control traffic entering and leaving your environment. Firewalls, are traditionally a network device that filters traffic based on configured access control list that defines good traffic and depending on the firewall captures/analyzes network packets and blocks bad traffic. -Firewall functionality implemented at the application level, Web Application Firewalls (WAF) operate similarly by specificly looking at Web traffic, over HTTP/HTTPS port 80 443 for malicious incoming from sources across the internet. +Web Application Firewalls (WAF) operate in a similar fashion to protect applications from incoming network traffic. They look at web traffic over HTTP/HTTPS (ports 80 and 443) respectively for malicious incoming traffic with your application as it's destination and can be configured to allow only known good requests. They can also to restrict the number of repeated bad attempts from a single source ip address. Third party hosted WAFs have the ability to monitor for and mitigate large distributed denial of service attacks. ### Example -If your public facing URI/URL for your application is hxxps://yourapplication.org/login +**If your public facing URI/URL for your application is hxxps://yourelixirapplication.org/login:** + +*The following is an example of requests that can come from across the internet targeting your application +from the same source IP 555.555.555.555 for instance:* ``` -The following is an example of requests that can come from across the internet targeting your application from the same source IP 123.123.123.123 for instance: hxxps://yourelixirapplication.org/secret hxxps://yourelixirapplication.org/admin hxxps://yourelixirapplication.org/login?user=test hxxps://yourelixirapplication.org/login?user=test&pass=test +hxxps://yourelixirapplication.org/login?user=';&pass=/www/app/... ..... ``` -Your site will handle these incoming requests either by returning 404 responses, etc. Imagine receiving thousands of these requests, however, as can be generated by automated tools freely available to malicious users. If your server/service processing these request was not built/designed to anticipate this scenario, the server could crash. +Your site will handle these incoming requests either by returning 404 responses, or other, depending on your configuration. + +Imagine receiving thousands of these requests. Automated tools are freely available to malicious users who may attempt a variety of attacks, like triggering a denial of service. If while building the server/service this scenario was not anticipated, the server could crash and your legitimate users won't be able to login to your application. + +A WAF can be configured to limit the number of tries from the same IP address. In the above example, if the same IP is the source for more than 100 of these attempts within 5 seconds, the WAF can prevent those requests from reach your application. + +### Prevention + +Per OWASP, consider limits on the following (please see Rate Limiting References below): + +* Execution timeouts +* Max allocable memory +* Number of file descriptors +* Number of processes +* Request payload size (e.g., uploads) +* Number of requests per client/resource/source ip address +* Number of records per page to return in a single request response + +When rate limiting a new action, begin by asking these questions: + +* "What are the maximum number of calls to my action that a reasonable non-malicious user would feasibly make in a given time period?" +* "Is calling this action an expensive operation? If yes, how many calls in a minute would be enough to overburden the service?" +* "Is this action a candidate for brute force attacks?" (E.g. passwords, authentication tokens, one time passcodes) + +If the answer to one or more of those questions is yes, consider putting a limit on the number of times that the action can be called. Good rate limiting keeps in mind legitimate use cases and does not block regular user functionality, but protects the service from malicious or burdensome behavior. + +More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. -A WAF can be configured to limit the number of tries from the same IP address. In the above example, if the same IP is the source for more than 100 of these attempts within 5 seconds, the WAF can ensure those requests don't reach your application. ### Rate Limiting References 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting 2. https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md +3. https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html ## Principle of Least Privilege From 1ea125ea06ec121c1a048c973831b516a1ffba10 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:12:37 -0700 Subject: [PATCH 09/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index befdfb6..303145f 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -63,7 +63,7 @@ When building an application, it is necessary to consider approaches to manage t When resources are not well managed, applications become vulnerable to negative impacts in performance, service outages, and denial of service attacks, in which a malicious actor takes advantage of resource limitations to intentionally overwhelm and crash a system. -Uncontrolled Resource Consumption is ranked 23rd on the list of most dangerous software weaknesses. (https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html). Implementing rate limiting is one security best practice that can help mitigate the likelihood of an application inadvertently or being deliberately triggered into consuming vital resources. +Uncontrolled Resource Consumption is ranked 23rd on the [list of most dangerous software weaknesses](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html). Implementing rate limiting is one security best practice that can help mitigate the likelihood of an application inadvertently or being deliberately triggered into consuming vital resources. ### Implementation Approaches There are multiple approaches to implementing rate limiting within an application and in general the approach is based on anticipating at least one of the following problematic scenarios: From 3e5ab0c413986ec041b0dad8ccc027f99fcbd726 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:13:27 -0700 Subject: [PATCH 10/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 303145f..854af95 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -89,7 +89,9 @@ For instance, an application that allows users to submit documents will want to ### Example -The Elixir language has a built-in rate-limiter called Hammer (https://hexdocs.pm/hammer/frontpage.html). Let's say there is an application that assigns users a userID and allows users to upload photos. Developers could decide to apply limits based on userId as in the example below. +When building Elixir applications, we recommend using the rate limiting library [Hammer](https://hexdocs.pm/hammer/frontpage.html). Let's take a look at how one would use it! + +Let's say there is an application that assigns users a userID and allows users to upload photos. Developers could decide to apply limits based on userId as in the example below. Note, the check_rate function below takes 3 arguments: From 2f873ff9efe89e54b7c122ba79290d9cab7a7958 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:17:39 -0700 Subject: [PATCH 11/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 854af95..bcac645 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -95,10 +95,11 @@ Let's say there is an application that assigns users a userID and allows users t Note, the check_rate function below takes 3 arguments: -1. The first is what we've decided apply the limit to, in this case, the userID. Each user has a unique userID. -2. The second, 60_000, represents the number of milliseconds in 1 minute (1000 milliseconds per 1 second, 60 seconds in 1 minute) -3. The last, 5, represents the number of times the userID can appear to have done a particular action before we stop them. In this case, 5 times. -4. The user is able to upload 5 photos (action) within a given minute before being blocked or stopped. +1. The first is what we've decided apply the limit to - in this case a unique identifier from the `userID`. +2. The second argument (`60_000`) represents the number of milliseconds in 1 minute +3. The last argument represents the number of times the identifier (our first argument) can appear to have done a particular action before we stop them. In this case, 5 times. + +Ultimately we've created a case statement where the user is able to perform 5 upload photos actions within a minute before being blocked or stopped. ``` # limit file uploads to x per minute per user From 6ae39dc036a87f5aff5bc6b28a1f899528001fec Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:18:00 -0700 Subject: [PATCH 12/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index bcac645..7067cdd 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -102,13 +102,15 @@ Note, the check_rate function below takes 3 arguments: Ultimately we've created a case statement where the user is able to perform 5 upload photos actions within a minute before being blocked or stopped. ``` -# limit file uploads to x per minute per user -userId = getUserId() -case Hammer.check_rate("action:#{userId}", 60_000, 5) do - {:allow, _count} -> - # let them do it - {:deny, _limit} -> - # nope too many +defmodule PhotoStorage do + def upload(userID, _file) do + case Hammer.check_rate("action:#{userId}", 60_000, 5) do + {:allow, _count} -> + # let them do it + {:deny, _limit} -> + # nope too many + end + end end ``` From 65afa69b9cec1f3c51349d9e9496f4d52dbd6047 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Wed, 15 Feb 2023 07:18:40 -0700 Subject: [PATCH 13/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 7067cdd..ad2896d 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -167,7 +167,7 @@ More often than not, rate limiting should be as specific as possible. For instan -### Rate Limiting References +### Resources 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting 2. https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md 3. https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html From 648aa5e5342175ee85125fcbaedbd936973641cd Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 17 Feb 2023 11:04:43 -0700 Subject: [PATCH 14/17] Update modules/3-ssdlc.livemd Co-authored-by: Holden Oullette <6202965+houllette@users.noreply.github.com> --- modules/3-ssdlc.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index ad2896d..80b652b 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -101,7 +101,7 @@ Note, the check_rate function below takes 3 arguments: Ultimately we've created a case statement where the user is able to perform 5 upload photos actions within a minute before being blocked or stopped. -``` +```elixir defmodule PhotoStorage do def upload(userID, _file) do case Hammer.check_rate("action:#{userId}", 60_000, 5) do From 8dab5de678246d01c5edb09345534eccc9c2ab1b Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 17 Feb 2023 11:31:05 -0700 Subject: [PATCH 15/17] Update 3-ssdlc.livemd Rearranged lines 143-151 and 153-161 per comment --- modules/3-ssdlc.livemd | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 80b652b..83e9715 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -87,6 +87,16 @@ Application rate limiting involves limiting interactions with functionality with For instance, an application that allows users to submit documents will want to limit file size and the number of repeated upload attempts. Users who upload gigantic files or who try to send too many files back-to-back could case a crash. Implementing rate limiting around the file upload functionality will help ensure that components of the application that respond to unpredictable or intentionally malicious user input, will not exceed the application's server processing capacity or available storage space. +When rate limiting a new action, begin by asking these questions: + +* "What are the maximum number of calls to my action that a reasonable non-malicious user would feasibly make in a given time period?" +* "Is calling this action an expensive operation? If yes, how many calls in a minute would be enough to overburden the service?" +* "Is this action a candidate for brute force attacks?" (E.g. passwords, authentication tokens, one time passcodes) + +If the answer to one or more of those questions is yes, consider putting a limit on the number of times that the action can be called. Good rate limiting keeps in mind legitimate use cases and does not block regular user functionality, but protects the service from malicious or burdensome behavior. + +More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. + ### Example When building Elixir applications, we recommend using the rate limiting library [Hammer](https://hexdocs.pm/hammer/frontpage.html). Let's take a look at how one would use it! @@ -121,6 +131,16 @@ At the network level, a firewall can be configured to sit between the internet a Web Application Firewalls (WAF) operate in a similar fashion to protect applications from incoming network traffic. They look at web traffic over HTTP/HTTPS (ports 80 and 443) respectively for malicious incoming traffic with your application as it's destination and can be configured to allow only known good requests. They can also to restrict the number of repeated bad attempts from a single source ip address. Third party hosted WAFs have the ability to monitor for and mitigate large distributed denial of service attacks. +Per OWASP, consider limits on the following (please see Rate Limiting References below): + +* Execution timeouts +* Max allocable memory +* Number of file descriptors +* Number of processes +* Request payload size (e.g., uploads) +* Number of requests per client/resource/source ip address +* Number of records per page to return in a single request response + ### Example **If your public facing URI/URL for your application is hxxps://yourelixirapplication.org/login:** @@ -143,29 +163,9 @@ Imagine receiving thousands of these requests. Automated tools are freely avail A WAF can be configured to limit the number of tries from the same IP address. In the above example, if the same IP is the source for more than 100 of these attempts within 5 seconds, the WAF can prevent those requests from reach your application. -### Prevention - -Per OWASP, consider limits on the following (please see Rate Limiting References below): - -* Execution timeouts -* Max allocable memory -* Number of file descriptors -* Number of processes -* Request payload size (e.g., uploads) -* Number of requests per client/resource/source ip address -* Number of records per page to return in a single request response - -When rate limiting a new action, begin by asking these questions: - -* "What are the maximum number of calls to my action that a reasonable non-malicious user would feasibly make in a given time period?" -* "Is calling this action an expensive operation? If yes, how many calls in a minute would be enough to overburden the service?" -* "Is this action a candidate for brute force attacks?" (E.g. passwords, authentication tokens, one time passcodes) - -If the answer to one or more of those questions is yes, consider putting a limit on the number of times that the action can be called. Good rate limiting keeps in mind legitimate use cases and does not block regular user functionality, but protects the service from malicious or burdensome behavior. - -More often than not, rate limiting should be as specific as possible. For instance, it is better to add rate limiting on a single GraphQL type than to add a generic limit to the entire /GraphQL endpoint. - +### QUIZ +"Using the Hammer library, protect the provided function with these specifications..." ### Resources 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting From a32131f12df23bdc43ca3e701863df90c5f6c653 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 17 Feb 2023 12:33:24 -0700 Subject: [PATCH 16/17] Update 3-ssdlc.livemd --- modules/3-ssdlc.livemd | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 83e9715..1510671 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -165,7 +165,44 @@ A WAF can be configured to limit the number of tries from the same IP address. ### QUIZ -"Using the Hammer library, protect the provided function with these specifications..." +***Using the Hammer library, protect the provided function with these specifications: limit each user to 3 login attempts in 1 minute*** + +```elixir +defmodule LoginAttempt do + def login(user, attempt) do + # code below to be added here + end + end +end +``` + +*Uncomment the line (1-3) that indicates the code block that goes into the funtion above* + +``` +# answer = :1 +# case Hammer.check_rate("login_try:#{user}", 60_000, 3) do +# {:allow, _count} -> +# # try again +# {:deny, _limit} -> +# # lock out for 10 min +# ------------------------------------------------------ +# answer = :2 +# case Hammer("login_try:#{user}", 60_000, 3) do +# {:allow, _count} -> +# # try again +# {:deny, _limit} -> +# # lock out for 30 min +# ------------------------------------------------------ +# answer = :3 +# case Hammer.check_rate("login_try:#{user}", 30_000, 100) do +# {:allow, _count} -> +# # try again +# {:deny, _limit} -> +# # lock out for 5 min + +IO.puts(answer) +``` + ### Resources 1. https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#rate-limiting From 83d036a6ea4dddf1e39ad1191a03bb33602030b9 Mon Sep 17 00:00:00 2001 From: hvalkerie19 <61711715+hvalkerie19@users.noreply.github.com> Date: Fri, 17 Feb 2023 12:48:28 -0700 Subject: [PATCH 17/17] Update 3-ssdlc.livemd --- modules/3-ssdlc.livemd | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 1510671..57fc48c 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -69,15 +69,15 @@ Uncontrolled Resource Consumption is ranked 23rd on the [list of most dangerous There are multiple approaches to implementing rate limiting within an application and in general the approach is based on anticipating at least one of the following problematic scenarios: * Malicious actor-generating abusive traffic designed to force the application into a compromised state -* Malicious or legitimate users perform large load activities that requires significant processing power -* Malicious or legitimate users sending large number of queries, often repeatedly to the service -* Malicious or legitimate users sending large number of queries in a narrow timeframe +* Malicious or legitimate users perform large load activities that require significant processing power +* Malicious or legitimate users sending a large number of queries, often repeatedly to the service +* Malicious or legitimate users sending a large number of queries in a narrow timeframe Rate limiting can be implemented to protect against a variety of attacks or abuses by: * Preventing Denial Of Service attacks (limiting the number of calls to resource expensive endpoints) * Limiting brute force attempts (such as on one time codes and passwords) -* Programmatic abuse of services +* Addressing programmatic abuse of services There are generally two approaches to rate limiting: that which occurs at the application level, and that which occurs at the network level. @@ -125,21 +125,11 @@ end ``` ### Network Level Rate Limiting -Network level rate limiting involves limiting the internet traffic that is destined for the application's host, web server, or web services. In web applications, when a client makes a request for an application's resources by internet address, that request is made using the HTTP/HTTPS protocol across the internet and is then the service responds using an HTTP response status code indicating if the resource was successfully returned or if there has been an error, or other message as appropriate. +Network level rate limiting involves limiting the internet traffic that is destined for the application's host, web server, or web services. In web applications, when a client makes a request for an application's resources by internet address (via DNS <-> URL domain), that request is made using the HTTP/HTTPS protocol across the internet. Then the service responds using an HTTP response status code indicating if the resource was successfully returned, if there has been an error, or other message as appropriate. -At the network level, a firewall can be configured to sit between the internet and your application servers/services to control traffic entering and leaving your environment. Firewalls, are traditionally a network device that filters traffic based on configured access control list that defines good traffic and depending on the firewall captures/analyzes network packets and blocks bad traffic. +At the network level, a firewall can be configured to sit between the internet and your application servers/services to control traffic entering and leaving your hosting environment. Firewalls, are traditionally a network device that filters traffic based on a configured access control list that defines good traffic and, depending on the firewall captures/analyzes network packets, and blocks bad traffic. -Web Application Firewalls (WAF) operate in a similar fashion to protect applications from incoming network traffic. They look at web traffic over HTTP/HTTPS (ports 80 and 443) respectively for malicious incoming traffic with your application as it's destination and can be configured to allow only known good requests. They can also to restrict the number of repeated bad attempts from a single source ip address. Third party hosted WAFs have the ability to monitor for and mitigate large distributed denial of service attacks. - -Per OWASP, consider limits on the following (please see Rate Limiting References below): - -* Execution timeouts -* Max allocable memory -* Number of file descriptors -* Number of processes -* Request payload size (e.g., uploads) -* Number of requests per client/resource/source ip address -* Number of records per page to return in a single request response +Web Application Firewalls (WAF) operate in a similar fashion to protect applications from incoming network traffic. They look at web traffic over HTTP/HTTPS (ports 80 and 443) respectively for malicious incoming traffic with your application as it's destination and can be configured to allow only known good requests. They can also restrict the number of repeated bad attempts from a single source ip address. Third party hosted WAFs have the ability to monitor for and mitigate large distributed denial of service attacks. ### Example @@ -163,6 +153,16 @@ Imagine receiving thousands of these requests. Automated tools are freely avail A WAF can be configured to limit the number of tries from the same IP address. In the above example, if the same IP is the source for more than 100 of these attempts within 5 seconds, the WAF can prevent those requests from reach your application. +When implementing rate limiting, consider limits on the following (please see Rate Limiting References below): + +* Execution timeouts +* Max allocable memory +* Number of file descriptors +* Number of processes +* Request payload size (e.g., uploads) +* Number of requests per client/resource/source ip address +* Number of records per page to return in a single request response + ### QUIZ ***Using the Hammer library, protect the provided function with these specifications: limit each user to 3 login attempts in 1 minute***