diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd
index 5ce692b..57fc48c 100644
--- a/modules/3-ssdlc.livemd
+++ b/modules/3-ssdlc.livemd
@@ -57,13 +57,35 @@ 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. Simply put - modern applications have a lot of things happening!
-* Preventing Denial Of Service attacks (limiting the number of calls to expensive endpoints)
+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, 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.
+
+### 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:
+
+* Malicious actor-generating abusive traffic designed to force the application into a compromised state
+* 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
-### Prevention
+There are generally two approaches to rate limiting: that which occurs at the application level, and that which occurs at the network level.
+
+### Application Level Rate Limiting
+
+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.
+
+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:
@@ -75,6 +97,118 @@ 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.
+### 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!
+
+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:
+
+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.
+
+```elixir
+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
+```
+
+### 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 (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 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 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://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:*
+
+```
+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, 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.
+
+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***
+
+```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
+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
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.