Creating an Inclusive Django Community with Kenya Phelps
Published July 15, 2026
This video features Aayush Gauba at DjangoCon US 2025 in Chicago, Illinois, USA.
This talk was presented at: https://2025.djangocon.us/talks/beyond-rate-limiting-building-an-active-learning-defense-system-in-django/
LINKS:
Follow Aayush Gauba 👇
On GitHub: https://github.com/aayushgauba
Website: https://gauba.org/aayush/
Follow DjangoCon US 👇
https://fosstodon.org/@djangocon
https://x.com/djangocon
Follow DEFNA 👇
https://www.defna.org/
Video production by the presenter and DjangoCon US 2025 volunteers.
Aayush Gauba presents AIWAF, an open-source, Django-native firewall intended to give smaller organizations layered web defenses without requiring a dedicated security team. Its middleware checks headers and IPs, learns suspicious URL tokens from failed requests, applies rate limits and honeypot timing checks, validates UUIDs, logs traffic, and uses an unsupervised isolation forest to flag anomalies before additional thresholds determine whether to block them. He emphasizes configurability and safeguards against false positives, while noting that anomaly detection needs traffic logs and periodic retraining; future work includes broader framework support and detecting coordinated attacks without adding too much latency.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: Thank you so much guys. Um and thank you guys for joining me here. So I am here to explore a simple but powerful question. What if your Django app could actually defend itself and get smarter over time And that is actually what AIWEF is all about. It's an open source Django native firewall that learns from real web traffic. For flood it can also catch scrubbing attacks, subtle issues like UID tampering and get smarter over time. Now by the end of the session, the goal is to not only understand how it works under the hood. but also how you can apply it without really needing a dedicated security team So before diving into what AIWAF actually is, I'll introduce myself.
Speaker 1: So I am Ayush Kaba and I'm a student and a researcher. at Southern Illinois University Edwardsville. Now my academic focus is quantum-inspired AI algorithms, which is basically how you can use principles from quantum computing to inspire new architectures. for machine learning. Now outside that research I'm also very passionate about applied security and open source projects. And um I think security today is a necessity, not a luxury. But the problem really is there's a lots of bad actors constantly probing for weaknesses. And the most vulnerable organizations are often the ones with the least resources. Now that often includes nonprofit small businesses,
Speaker 1: for which enterprise-level solutions might be very expensive and complex. Which might put it out of reach for these groups. That's why I think open source security is so important. It levels out the playing field given giving smaller organizations a fighting chance as big as the big players. Without really the barrier of cost. Now, as we all know, open source means transparency and collaboration, and the more the people get involved, the more the tools get stronger over time. Diving a little more into why security needs to be open source. Now, the really the thing is with um security there needs to be a community audit and without community audit you risk um bugs or misconfigurations or sometimes even unintentional backdoors can go through unnoticed.
Speaker 1: By contrast when you have open source security tools they are more transparent, peer-reviewed and customizable Now because of inherent open nature of open source that means anybody can test these systems and contribute to improvements. And security really needs to be a community effort and uh the more people contribute the more stronger it gets And it also um gives uh smaller organizations and nonprofits a fighting chance So the main thing in this presentation is how it how AIWAF actually works under the hood, the method it uses to validate requests and also detect anomalies and block malicious traffic Secondly, I'll also show how easy it is to plug AI WAF
Speaker 1: into your own projects. The idea is not just to make it theoretical, but something you guys can take away from this and apply directly. So this is a middleware level security. It's um you can add or delete parts of the middleware as you want to. So I'll be going into how each middleware works uh middleware by middleware. Now onto the header middleware. Now as it implies as the name implies now the main goal of this headerware is to inspect the headers of every incoming request. Now legitimate browsers have a consistent set of headers, but uh when you have bots and scrapers, they often reveal themselves with missing fake or strange headers. Now when you validate this early, we can block bad traffic even before it ever reaches the app And um instead of just blocking um
Speaker 1: if one thing is present or not, uh the system actually combines um scoring model to make decisions. Now the validation basically works in layers first. It checks whether basic headers like user agent and except are present. Then it looks at the user agent string for known malicious keywords like you have a Python request and then curl wget or maybe fake Mozilla strings. Then it uses a combination of headers that don't actually make sense, like an old browser with a modern protocol, and then it calculates a quality score based on header completedness. Now if the score is too low, the request is considered outright suspicious and blocked.
Speaker 1: Now in practice what this really means is that your normal users and your trusted bots like the Google bot or BingBot, the actual uh search engine scraper bots actually pass through. But when you actually have malicious scrapers or outdated scanners, they get blocked with a 403 forbidden. And the response is returned as a JSON with a clear error message. This way your application stays secure without wasting any resources on bad request. Now this is actually what will catch 90% of bad bots, scrapers, and sometimes even vulnerability scanners. And uh I'll dive into a short example to show kind of how it really works. So let's assume we have these two requests right here.
Speaker 1: Um so uh the first one is um the kind of request that you would see for a static stealth sheet and the second one is actually a malicious request. Let's kind of deep dive into how different those two requests are. So this, if you look at this log entry, this is a normal static file request. The IP shows us who made the request and the timeshare stamp timestamp shows when it actually happened And then the request line is a simple get for a CSS file under the static, which as we all know browsers do when they need uh when they load style sheets or files. The response is 200 okay, which means it succeeded and it was 44 bytes, which is
Speaker 1: kind of what you would see for a small style sheet. Now the referrer field shows that the request came from a page on your website. org. Now your website is a fictional site if that exists and this is actually not from that. And so everything else makes sense. The user string also matches a legitimate Chrome browser on macOS Finally, the request completed in just 35 milliseconds. Nothing kind of suspicious here. This is the kind of traffic that AIVAF would let in through without interference. Now this is what it looks like when AIF would actually step in. The attacker IP is trying to access web admin. php. Which is a common target for automated web scanners looking for misconfigured admin panels.
Speaker 1: Notice the request is missing basically two things, a user agent and a referral, which makes it even more suspicious Now instead of giving um them a clue by serving a 404 or worse, yeah I 've actually blocked it with 4034 button. The response was only 31 bytes and completed in 54 milliseconds, meaning the attacker got actually nothing useful. This is actually the value here. Uh the bad traffic is stopped even ever before it reaches your app logic. Now IP and keyword middleware. So this was the first middleware that was actually developed. IP uh blocking and exemption is actually now in every middleware. So in this
Speaker 1: this in this particular middleware it starts with an IP check. If um an IP is blacklisted, it's blocked immediately. And uh if it's exempt it's allowed uh to be extra safe. Exemptions are actually checked twice before blocking so that your trusted sources aren't accidentally locked out. For example, I used to play around with the middleware checking how security works and on a lot of occasions I actually ended up being blocked. So I had to put myself in the whitelist. Um and uh we have a centralized manager instead of just using Django models. And the main reason for that is um That the support right now is for Django models, but the goal is to extend that to CSV or JSON. But that's for uh upcoming version updates
Speaker 1: So in this one the um path is tokenized into keywords so these tokens are checked against both static suspicious keywords and dynamic learned ones from traffic. Now um the main thing here if a token matches and it's not really exempt the request is blocked and um to give a more idea on how that really works. Is that the middleware automatically recognizes what keywords are actually safe in your project? It extracts them from Django routes, apps, configs, and model names. and explicit settings and a common setup also uh default save terms are also included. So context makes all the difference. So a lot of times your keywords are actually X uh
Speaker 1: SQLI or XSS signatures or maybe directory transversal attempts or suspicious file extinctions um or in hidden file perhaps if a pad does not exist in Django that's only when it's treated as actually suspicion because we don't want to end up blocking legitimate traffic Now the idea is not just to rely on static rules, it also learn from what attackers are probing for. So like I said, the um Tokens are only connect collected from failing requests like your 404 or 500, basically non-jjango paths, and counts how often they appear. So the top tokens are added automatically to the keyword store. Or maybe in this case since there's only Django's model support to keyword model.
Speaker 1: Um that way if attacker starts scanning for maybe PHP myadmin or backup. zip, AIWAV blocks them immediately without any manual updates. Now preventing false positive is just as important as blocking attacks. The main thing to notice here is that uh and a key part of this is that it automatically Gets all the keywords from your Django apps or routes and as well as model names to make sure that any legitimate users that probably look suspicious and maybe it's just a quirky user doesn't end up being blocked So now the main reason for that is this keeps uh protection strong without actually breaking real traffic.
Speaker 1: Now this also includes uh now another middle where is rate limiting. So um the main way that this actually works is that it tracks requests from each IP within a shorts uh Sliding window and if a request actually passes a soft limit, let's just say maybe um nine requests, the user gets a warning that hey um there's too many requests, but if they cross that threshold And ignore that then the IP address is blocked entirely. Now because it runs off of Django caching system, it's very fast and can work across um multiple servers, making it very effective for stopping brute force logins or DDoS outburst. So how it actually works is that each IP has a small list of timestamps
Speaker 1: stored in cache for every request. We remove the old entries and append the new one and save the list back. That's pretty much it. And that lets you check volume over the last uh n minutes and is most commonly five minutes. And um then we apply two thresholds, one for soft limits that triggers a 429 and another for floods that triggers an outright block. Yeah, this is very efficient because most of the time the list stored in cache is just a handful of entries Now all these thresholds are configurable in Django settings. You can tighten them up or maybe sensitive brows like login and maybe losen them for APIs because a lot of times if you apply this on APIs
Speaker 1: then a lot of um maybe um Web-based applications will end up being blocked because it would look like a um a DDoS style attack. But because it runs exactly through uh through Django cache, it works to whatever cache backend you're using, probably Redis And as always, in every single middleware, exempt IPs are and views are ignored completely, so you can tune this without breaking uh trusted traffic. So now this middleware is where AI really comes into play. And um before we dive in, what this actually does is that it uses machine learning like the name implies to look at traffic patterns and to decide what is normal and what is weird. Um
Speaker 1: and the model is an isolation forest um which in short terms it means it's unsupervised so you don't really need label the tag data and uh a main thing of what the parser does whenever you train the model is that it trains it it creates a new data set kind of which um creates uh a list of feature vectors like maybe path length, um how whether it contains bad keywords, how fast it responded, status code, how many requests are in that bist, and how many 404s we have seen from that I Now if the model says that it's analogous, then we do a few more checks before deciding to block. So now the main thing to notice here is that you don't just want to block just because the isolation for a
Speaker 1: set so. Now instead the activity of less five minutes are analyzed by that particular IP. Now for example if the hits are low, perfors are under 10, maybe bursts are under 15 and total requests are under 100, we treat it as an odd, but maybe it's a legitimate quirky client. Now, but if those thresholds are exceeded, that's a strong sign of malicious behavior. And um the IP ends up being blocked. Now this uh this actually ends up preventing false positives, uh which are the biggest risk with any anatomy uh detection Now uh the main thing is this constantly needs learning and um every and
Speaker 1: for real time every request is logged into cache with its time path. status and response this kind of builds up a short-term memory of activity for HIP. Now that data not only powers the um logic but also feeds back into the dynamic keyword discovery. Over time the retraining the isolation process model maybe ends up picking new behaviors that weren't really in the original rules. Now the main thing to know that is not really a static, it adapts as it sees more traffic. Now I think a key thing to cover also is how what an isolation force really is and how it really looks at data. Um so when we basically talk about um
Speaker 1: malicious detection in web traffic, most requests most uh web requests are basically straws in a haystack. They're most of the time harmless, repetitive, and expected. But instead we probably want to look uh for a needle. um that might uh be something dangerous. Now basically isolation workforce works exactly like a metal detector in this case And doesn't really tell us what exactly the object is, but quickly flags the unusual ones. Now instead of checking every straw, we only examine the flagged anomalies. Now then by our guardrail rules like checking for burst for force or malicious keywords actually helps us decide whether you know what we found was just was actually a needle
Speaker 1: or maybe it was just uh straw that look like a needle Now the beauty of isolation for us lies in its simplicity and practicality for web development. Now unlike unsupervised models, we don't really need pre-labeled data telling us what's actually good or bad. It figures that out by itself Now basically um long story short it works by randomly splitting features until an outlier is isolated and In a lot of cases anomalies are actually isolated much faster than normal data, and which is what it makes it very efficient. It also scales really nicely. So we can feed in tens of thousands of traffic logs without a used performance hit. And it turns out if you have
Speaker 1: a decent CPU and you don't really even need a CPU, a GPU for retraining And as as I already implied, retaining is simple. So that should be done based on requirements to make sure that the firewall stays updated as attack patterns involved. So this is actually the backbone for um AI WAP's adaptive defense. Now the training frequency. I guess one of the most common questions I got, probably we might get to this later as well, is how often should it be retrained? The simple answer is it depends on the volume of requests that your application handles If um your uh the model actually learns some real-world patterns in traffic.
Speaker 1: So if you have millions of requests per day, then you would you'll have enough to justify frequent Updates. Now if your site only ends up getting a few thousand requests daily, then training less often is actually fine. So the key thing to note here is that the training frequency actually scales linearly with the number of requests. The more data you collect, the faster the model can adapt. To new patterns. For example, an app serving a millions of requests per day probably benefits from daily retraining, whereas a small non smaller nonprofit that only handles a few thousand requests can retrain monthly Now a big thing to note here is that overtraining actually wastes resources, so the best idea is to align the schedule with your actual traffic.
Speaker 1: Now um the next middleware is honeypot uh honeypot timing. The main goal of this middleware is to watch how users move from a get page load to a post submit. Now real users take time, uh, but bots often submit instantly or hit the wrong methods. Um so when a client calls a method uh that the view doesn't really support, like if we have a view that only has a um Get request, but it ends up getting a post request that's probably a bot. So that ends up getting getting blocked. Now, as always, exempt IPs are always respected. So if um And the method also returns clear responses. So it's either a block or a page or a page expired
Speaker 1: or an exempt. So now if uh let's just say if uh because it's all built into cash, if a page ends up um being idle for more than five minutes. This muralware actually um ends up returning a 429 asking the user to reload. Okay. Yeah. Now uh each get request is timestamped in post actually there's two things checked. So does the view actually allow post and uh did the user wait long enough? Normal forms need at least a second, but uh login can sometimes be very quick, so we allow a little uh less time in there. Now I have the pace set open for too long, maybe over four minutes. We don't really block and we just ask the user to reload with a
Speaker 1: 429 page expired. But for other requests like put delete patch, it's only allowed if the view actually supports them And the basic goal, the basic um thing that this view basically does this muralwell actually does is that if a method is not allowed by a view, then it's straight outright blocked. That's a strong sign that someone is actually trying to uh hack into your website. Now enforcement is graded. If a client actually submits too fast um then it's blocked outright And it's uh 403 for suspicious timing and 405 for wrong methods. Now a page is simply still. Then the user is not uh punished and simply
Speaker 1: has to reload. Now as always exemptions always win. So if um an exempt IP zends up um Messy mm um playing around with the website then uh it doesn't end up being blocked. But the main thing is that the normal request goes flows through unchanged. Now the um now this middleware basically checks whether uh if I UUID in its URL and is it valid. Um so every time a UUID is basically in a URL, it's sanity checks before it executes. Now if a UUID does not result to any real object in a Any UUID primary key model in the current app, then it's treated as a tampering attempt or an enumeration.
Speaker 1: Now legitimate users often hit real objects but scra but uh bots, website scanners often spray random UUIDs. Um and that's the main thing here. If uh if a UUID does not exist it ends up getting blocked straight out So the main thing to notice here is that this middleware fires at process view and uh the first thing that is read is the UUID parameter. and discover the app for that view and then scan the models for those uh using pre-UUID primary keys. Now if that particular um UUID does not exist in any of them it ends up getting blocked but if it does then it's allowed. Now doing this actually makes sure that
Speaker 1: your view code keeps clear is clean and it saves DB work on invalid objects Now a key thing to note is exemptions always apply. So if your internal tools or uh health checks won't end up getting blocked But if someone ends up supplying a malformed UID, there's um we end up swallowing type errors and treat it as a miss, but if there's a large difference then it ends up being blocked. But in large projects, scanning a re UUID primary key model can often be very costly. So you might want to optimize by whitelisting which models you want to check per route or caching the negative lookups briefly. Finally, the main goal of this MerrillBare is
Speaker 1: to only validate whether a UUID exists or maybe based on that block or allow. But if you want you can enforce authorization in your view or your query set. Now uh on to the middleware logger. So the main thing for this is um now as um as by this time AI WAV um all needs data to make decisions. So that's the main goal here. So the logger middleware exists to make sure that AI web always has data even when standard access logs are not available. So every request ends up getting passed through Django through a request log model. And this includes the IP method
Speaker 1: path. status code, timing and all that user agent later. This data is actually used by the trainer which consumes for building um an anomaly models So the main thing to note here is that each entry is rich enough to reconstruct traffic patterns. We log the IP, the method, and the path. We also track how long the request took, um the response code and metadata like user agent and referrer. To prevent storage bloat, uh long feel like maybe long paths are often uh trunicated. Now the main goal of this is to convert it to a format that the trainer already expects. So now
Speaker 1: this supports both uh string lines and dictionaries in the common log format. This way you don't have to change trainer logic every single time. It can consume logs just like it would server logs. Now on to the setup. The setup is actually pretty simple. You have to um and I'll go through it step by step. So first thing you have to install the um you have to install AI WAF into your particular project. Um And right now the main it it exists as this and we I'm actually focusing on building it for others so that might change into Django AI VAV maybe in the near future. So then you would have to add it to your installed apps and give it access to logs and without logs
Speaker 1: um the at least the AI part would not be able to function. And if you don't have logs, you can add the logger middleware right here. And the main thing is you can this is very customizable So let's say if I don't need um the AI anomaly middleware as um let's say if you have a f if you're using a free tire on AIWS. Probably you cannot support retraining because it's very computationally expensive. Um and that's and that's something that the free tire cannot support. So you can just remove that from there. And you can still use the rest of the middlewares as as it is. The main thing is if um the main thing is you don't really need all of the all of the middlewares.
Speaker 1: But the best advice is a a a layered approach would probably provide for the best defense. That's the main thing to note here. Then um to store data AIWEF actually needs models and um everything so you would have to make migrations and migrate to make sure that it syncs with your particular web app and make sure AIVAF is um available to run. Now um with that being said the future the future work is uh basically to make it platform agnostic. Now that means extending support to Flask, uh Fast API or Express or even PHP frameworks like WordPress or Larval. Now I think developers shouldn't um choose a a different fireball based on what stack they're using.
Speaker 1: The long-term version is a universal web that you can plug in into any application with just a single line of configuration. Also, another goal is to um is to is the intelligence layer. Right now AI VAF only uses rule-based heuristics. uh with uh lightweight anomaly detection. But in future the main goal is to uh train deeper models to recognize subtle attack patterns across sessions. Things like behavior fingerprinting could also be very useful. For instance another example would be instead of just blocking one bad request, the model could detect coordinated probing attempts over time. The challenge in doing this is uh to not slow down performance.
Speaker 1: We don't want um each uh request to take more than, you know, maybe uh 35 to 50 milliseconds so the research is not only about building smarter faster AI models but also to build light also to make it lightweight enough so that it can scale in production And um yeah, um like I said right now is it only has me working, but it would probably benefit uh from uh getting more contributors. So whether it's uh storing the repo, reporting issues, writing code, every action helps. And the main idea is that the project gets stronger with every new contributor. So that's actually the website for AIV, and um I would like to thank DigitalOcean for sponsoring that.
Speaker 1: Um And uh thank you guys for actually listening to me. I hope this was useful and I can take questions now if you guys want.
Speaker 2: Thank you. That was super interesting. Are there any plans to actually pre-train the model on open sources of like in your repo it has Nginx logs, right? But what kind of ever access log to actually provide some knowledge of what's already out there. biggest benefits we have in the cybersecurity community is that open information sharing, right? So as opposed to training individual models, actually sharing those either the Nginx training data or actually com sharing the models themselves. Did you have any kind of plans or thoughts around that
Speaker 1: Uh yeah, actually there's actually a pre-trained model already available. But the main thing to note here is that that's only trained on six thousand six thousand lines of uh log data. So it's it's a good start, but it's not I wouldn't say that it's um a big jump um to retraining. But um that's why I actually implied on retraining and everything. But um I have a few plans on uh probably um either building synthetic data around that and but it's really hard to kind of model real-time real world behavior in synthetic logs. So that's another challenge, but I am actually exploring on that.
Speaker 3: Yeah, hi. Do you have any or do you have any intentions of supporting Django channels or WebSockets with this?
Speaker 1: Um I haven't thought as far as um WebSockets uh probably because I am I am not very comfortable around them, but I'm learning them and everything. But I guess the closest thing would be the APIs, right? So right now what I was focusing on was um including encryption methods. With the IWA for encrypting the path, um the main challenge is um to build basically two packages around that. First that you could use from your application um to maybe the um API application to make sure that the um The the line is encrypted. But in terms of WebSockets, I I guess I'll have to read more around that and kind of figure out how I would design it to be more compatible with that and everything.
Speaker 1: Probably another middleware Uh but yeah.
Speaker 3: Thank you.
Speaker 4: Okay, so uh thank you. I just and please give our again a warm well around.
Its header middleware checks for required headers, suspicious user-agent strings, inconsistent header combinations, and an overall header-quality score. Low-scoring requests are blocked, while legitimate browsers and trusted search bots can pass.
Discussed at 3:18It derives safe terms from Django routes, apps, settings, and model names, then learns frequently seen tokens from failing requests such as 404s and 500s. Learned suspicious tokens can be blocked automatically, while known project terms help prevent false positives.
Discussed at 8:43It tracks each IP’s request timestamps in Django’s cache over a sliding window. A soft threshold returns HTTP 429, and exceeding a higher flood threshold blocks the IP; the limits can be configured and trusted IPs or views exempted.
Discussed at 10:59An unsupervised Isolation Forest evaluates request features, but an anomaly is not blocked on that signal alone. AIWAF also checks recent per-IP activity—such as request volume, bursts, and errors—and blocks when those guardrail thresholds indicate malicious behavior.
Discussed at 13:21Retraining depends on traffic volume: a high-traffic site may benefit from daily updates, while a small site with only a few thousand requests a day may retrain monthly. The speaker advises matching the schedule to real traffic rather than overtraining.
Discussed at 17:13It checks whether a client uses a method the view supports and whether it submits a form implausibly quickly after loading the page. Suspiciously fast submissions or unsupported methods are blocked; expired pages instead prompt the user to reload.
Discussed at 18:48When a URL contains a UUID, the middleware checks whether it matches an object in the relevant app’s UUID-primary-key models. A UUID with no matching object is treated as a tampering or enumeration attempt and blocked; the speaker notes that large projects may need per-route model allowlists or cached negative lookups.
Discussed at 21:06Install the package, add it to `INSTALLED_APPS`, provide request logs (using its logger middleware if needed), then run migrations. Middleware is customizable, so you can omit components such as anomaly detection, though the speaker recommends a layered setup for stronger defense.
Discussed at 24:55Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026