# Obsidio — full site content > Concatenated markdown of every public page. Generated dynamically; reflects the current published content. Re-fetched on each request. ======================================== # Home URL: https://obsidio.com/ # Test your defenses with real DDoS simulations. Realistic and verifiable simulations that give companies audit-ready proof of resilience and compliance. Request a Demo Learn More Obsidio lets you run controlled, realistic DDoS attacks against your own infrastructure — powered by 100,000+ globally distributed devices. Know exactly where you stand before a real attack hits. TRUSTED BY LEADING SWISS BANKS ### Threats are decentralized. Your testing should be too. Real DDoS attacks don’t come from a single datacenter. They come from thousands of compromised devices across the globe. Yet most resilience testing still relies on centralized load generators that can’t replicate actual attack patterns. The result? A false sense of security. Obsidio changes that — every simulation runs from real, ethically sourced devices worldwide, generating traffic patterns indistinguishable from a genuine attack. Core Capabilities ## Why DDoS resilience testing with Obsidio? Unmatched Realism ### 100,000+ real hardware devices Not virtualized instances. Not datacenter IPs. Real hardware devices and smartphones that generate traffic indistinguishable from a genuine botnet — so your WAF can’t cheat the test. Self-Service ### Configure. Test. Adapt. Retest. Built for WAF, LB, and red teams to run simulations on-demand. Deploy a rule change and validate it in minutes — no vendor scheduling, no consultants, no waiting. Verifiable Proof ### Audit-ready for FINMA, DORA, and NIS2 Every simulation produces cryptographically attested, tamper-proof reports. Compliance evidence your risk officer can hand directly to a regulator. Request a Demo ## Independent.Neutral.Verifiable. Switzerland’s reputation isn’t built on precision alone — it’s built on independence, neutrality, and accountability. Obsidio brings those same principles to resilience testing, combining Swiss governance with a worldwide device network that mirrors how real attacks actually happen. Request a Demo - 100,000+ distributed devices worldwide - Trusted by Swiss financial institutions - Real hardware — not virtualized instances - Swiss-built & operated + ## Resilience you can prove. Every simulation runs on real hardware, from real locations, against your real infrastructure. The results are cryptographically attested and tamper-proof — evidence that holds up to regulators, auditors, and boards. Not a vendor’s promise. Proof. ======================================== # About URL: https://obsidio.com/about/ ABOUT # Swiss resilience, engineered for trust. Obsidio was founded in Switzerland to help critical infrastructure and institutions prove their operational resilience. Built on Swiss values of precision, neutrality, and confidentiality. Request a Demo Our Mission ### Turning regulatory requirements into trusted resilience. Our mission is simple: to help FINMA-regulated institutions transform resilience testing into measurable, verifiable assurance. With Obsidio, banks, insurers, and financial market infrastructures can demonstrate compliance with confidence. Our Story ### Built in Switzerland, built for the world. Obsidio was developed in Switzerland as the only resilience testing platform tailored for FINMA requirements. Backed by Swiss expertise in financial services and security engineering, we combine regulatory alignment with cutting-edge decentralized technology, turning resilience testing into a compliance-ready process. What we do Obsidio transforms regulatory requirements into verifiable resilience, giving institutions proof of strength when it matters most. Our Values ## The principles we stand by. Our work is guided by principles that ensure resilience is more than a promise. We combine Swiss precision with ethical innovation to deliver compliance-ready, trustworthy simulations. These values shape everything we do, from technology to client relationships. - ResilienceStrength is proven, not promised. - TrustConfidential, neutral, and trustworthy. - ComplianceFINMA-aligned, audit-ready. - InnovationDecentralized, realistic, ethical, verifiable. - IntegrityAuthorization-first, zero misuse possible. ======================================== # Accessibility Statement URL: https://obsidio.com/accessibility/ LEGAL # Accessibility Statement Papers AG is committed to making the Obsidio website and platform accessible to as many people as possible, in line with the European Accessibility Act (EAA) and Swiss accessibility requirements. ## 1. Conformance status This website aims to conform with Web Content Accessibility Guidelines (WCAG) 2.2 level AA. Conformance status: partially conformant. Some content may not yet fully meet AA criteria; we are actively working to remediate these. ## 2. Measures we take - Semantic HTML with proper landmarks and headings. - Visible keyboard focus indicators on all interactive elements. - Respect for prefers-reduced-motion on animations and parallax. - Alt text on content images; decorative images marked as such. - Forms with associated labels and required-field indicators. - Color contrast tested against WCAG 2.2 AA targets. ## 3. Known issues Some embedded third-party content (Contact Form 7, cookie consent banner) may not yet meet the full AA criteria. We track and prioritise these issues continuously. ## 4. Feedback and contact We welcome feedback on the accessibility of Obsidio. If you encounter accessibility barriers, please contact us at sales@obsidio.com. We aim to respond within ten business days. ## 5. Enforcement If you are not satisfied with our response, you may escalate to the competent enforcement body in your jurisdiction. In Switzerland this is the Federal Department of Home Affairs (EDI). In the EU this is the national accessibility enforcement body designated under the EAA. ## 6. Last updated This statement was last reviewed on 2026-05-28. ======================================== # Benefits URL: https://obsidio.com/benefits/ KEY ADVANTAGES # DDoS resilience proof — not assumptions. Real hardware. Real attack patterns. Real proof. Obsidio’s resilience testing gives your security, compliance, and leadership teams verifiable evidence that your infrastructure holds — not a vendor’s best guess. Request a Demo Our Edge ## Why leading institutions choose Obsidio. ### Compliance-Ready Reporting Audit-ready reports mapped to FINMA, DORA, and NIS2. Hand them directly to a regulator — no reformatting required. ### Unmatched Realism 100,000+ real hardware devices and smartphones — not virtualized instances. Traffic your WAF can’t fingerprint, from the geographies you choose. ### Swiss Independence Built and operated in Switzerland by Papers AG. Independent, neutral, governed by Swiss law. No foreign jurisdiction dependencies. ### Self-Service Testing Configure, test, adapt, and retest on-demand. Built for WAF, LB, and red teams to operate independently — no vendor scheduling, no consultants. Why Choose Us ## What makes Obsidio different. Distributed, Not Centralised Traditional DDoS testing fires traffic from a handful of datacenter servers. Your WAF blocks it on IP reputation before your real defenses are ever engaged — giving you a passing score that means nothing. Obsidio’s 100,000+ real hardware devices generate traffic with the same geographic spread, IP diversity, and OS fingerprints as a genuine botnet. If your infrastructure survives this, it survives the real thing. Cryptographically Verified Every result is signed and tamper-proof. Regulators can independently verify the evidence — you cannot manipulate it, and neither can we. Controlled & Authorised Authorization-first by design. No simulation runs without explicit, verifiable consent from the asset owner. No misuse possible. Value for Stakeholders ## Benefits for every level of your institution. Request a Demo - C-LevelGive your CISO, CRO, and CTO a self-service platform that validates mitigation stacks with real-world attack traffic — and produces the metrics to prove it worked. - Risk & Compliance OfficersGenerate audit-ready reports aligned to FINMA, DORA, and NIS2. Documented, repeatable evidence of resilience — not a one-off vendor report. - Executives & BoardsVerifiable proof that your institution can withstand disruption. Cryptographically attested results your board can present to regulators and customers with confidence. + ## Resilience you can prove. Every simulation runs on real hardware, from real locations, against your real infrastructure. The results are cryptographically attested and tamper-proof — evidence that holds up to regulators, auditors, and boards. Not a vendor’s promise. Proof. ======================================== # Blog URL: https://obsidio.com/blog/ ======================================== # Brand Assets URL: https://obsidio.com/brand-assets/ Brand Resources # Brand Kit Official Obsidio assets for partners, press, and integrations. Please do not modify logos, colors, or typography without permission. ### USAGE POLICY For approved partner and press use only. Contact us before any public-facing usage. #1 ## Logo Variants PrimaryViolet mark, dark text SVG PNGGrayFull gray SVG PNGSecondaryViolet mark, white text SVG PNGWhiteFull white SVG PNG All files provided as SVG (vector) and PNG. Use SVG wherever possible. #2 ## Brand Colors PrimaryDigital Purple#5000E4BackgroundObsidian#141319Dark SurfaceDeep Indigo#210060AccentElectric Indigo#32089BText / LightWhite#FFFFFF Click any swatch to copy its hex value to clipboard. #3 ## Wallpapers LIGHTIcon right alignedLIGHTIcon centeredLIGHTIcon cropped rightDARKIcon cropped rightVIOLETIcon zoomedDARKShader Hover any wallpaper to download. High-resolution PNG or JPG. © 2026 Papers AG · Zug, Switzerlandsales@obsidio.com ======================================== # Contact URL: https://obsidio.com/contact/ CONTACT # Let’s talk ### Looking for help? Tell us about your resilience challenges. Whether you need a demo, technical support, or guidance on audit-ready reporting, our team will help you find the right solution with Obsidio. - Sales & Demos sales@obsidio.com - Technical Support support@obsidio.com Name* Email* Company* Message* By sending this form, you agree to our Terms & Conditions and Privacy Policy. Leave this field empty FAQ ## Frequently asked questions What is Obsidio?Obsidio is a Swiss DDoS simulation platform designed for critical infrastructure and companies. It provides controlled, realistic DDoS simulations that generate verifiable, audit-ready proof of operational resilience. Who needs DDoS simulations?Any organisation whose operations depend on online availability — banks, insurers, FMIs, energy and telecom providers, healthcare, government services, and large e-commerce. Anywhere FINMA, DORA, NIS2, or board-level resilience evidence is required. How does Obsidio differ from other testing providers?Traditional providers use a small number of cloud load generators. Obsidio orchestrates real, ethically sourced devices distributed worldwide, generating traffic that's indistinguishable from a genuine attack. Every result is cryptographically signed and independently verifiable. How do you ensure tests are safe and authorized?Every simulation requires explicit ownership verification — typically a DNS TXT record — before any traffic is generated. Tests run inside Trusted Execution Environments with full audit logging. No traffic can be launched against infrastructure you don't control. Will simulations disrupt our production systems?You define the intensity, duration, and scope. Most institutions run progressive simulations starting in a controlled window with conservative limits, then ramp up as confidence grows. Live metrics let you abort instantly. What evidence will we receive after a test?A cryptographically attested PDF report plus structured JSON data: full traffic profile, mitigation effectiveness, regulator-aligned control mapping, and tamper-proof signatures any auditor can verify. How does Obsidio support compliance?Reports map directly to FINMA operational resilience requirements, DORA testing obligations (Articles 24 and 25), and NIS2 incident-response expectations. Repeat the same scenario quarterly to show continuous improvement over time. Is Obsidio only for financial institutions?No — finance is our deepest expertise but the platform serves any critical-infrastructure operator. Healthcare, energy, telecom, government, SaaS, and large e-commerce all use Obsidio. Who develops and operates Obsidio?Obsidio is built and operated by Papers AG, a Swiss engineering firm specialising in regulated-industry security and compliance tooling. ======================================== # Cookie Policy URL: https://obsidio.com/cookie-policy/ This Cookie Policy was last updated on August 31, 2026 and applies to citizens and legal permanent residents of the European Economic Area and Switzerland. ## 1. Introduction Our website, https://obsidio.com (hereinafter: “the website”) uses cookies and other related technologies (for convenience all technologies are referred to as “cookies”). Cookies are also placed by third parties we have engaged. In the document below we inform you about the use of cookies on our website. ## 2. What are cookies? A cookie is a small simple file that is sent along with pages of this website and stored by your browser on the hard drive of your computer or another device. The information stored therein may be returned to our servers or to the servers of the relevant third parties during a subsequent visit. ## 3. What are scripts? A script is a piece of program code that is used to make our website function properly and interactively. This code is executed on our server or on your device. ## 4. What is a web beacon? A web beacon (or a pixel tag) is a small, invisible piece of text or image on a website that is used to monitor traffic on a website. In order to do this, various data about you is stored using web beacons. ## 5. Cookies ### 5.1 Technical or functional cookies Some cookies ensure that certain parts of the website work properly and that your user preferences remain known. By placing functional cookies, we make it easier for you to visit our website. This way, you do not need to repeatedly enter the same information when visiting our website and, for example, the items remain in your shopping cart until you have paid. We may place these cookies without your consent. ### 5.2 Statistics cookies We use statistics cookies to optimize the website experience for our users. With these statistics cookies we get insights in the usage of our website. We ask your permission to place statistics cookies. ### 5.3 Marketing/Tracking cookies Marketing/Tracking cookies are cookies or any other form of local storage, used to create user profiles to display advertising or to track the user on this website or across several websites for similar marketing purposes. ## 6. Placed cookies ### Google Analytics Statistics Consent to service google-analytics #### Usage We use Google Analytics for Statistics. Read more about Google Analytics #### Sharing data For more information, please read the Google Analytics Privacy Statement. #### Statistics Name _ga Expiration 2 years Function Assigns a randomly generated client ID so returning visits are counted as one visitor. Name _ga_5G3B3MC5KE Expiration 2 years Function Stores the session state and session counter for this Google Analytics 4 property. ### Microsoft Clarity Statistics Consent to service microsoft-clarity #### Usage We use Microsoft Clarity for Statistics. Read more about Microsoft Clarity #### Sharing data For more information, please read the Microsoft Clarity Privacy Statement. #### Statistics Name _clck Expiration 1 year Function Stores a Clarity user ID so repeat visits are recognised. Name _clsk Expiration 1 day Function Groups the pageviews of one visit into a single session recording. Name CLID Expiration 1 year Function Identifies the first time Clarity saw this browser, on the Clarity domain. on www.clarity.ms Name ANONCHK Expiration 10 minutes Function Indicates whether the session ID is used for telemetry. on c.clarity.ms Name MUID Expiration 1 year Function Identifies unique browsers across Microsoft domains, used for analytics and advertising. on c.clarity.ms Name SM Expiration session Function Synchronises the MUID identifier across Microsoft domains. on c.clarity.ms Name MR Expiration 7 days Function Indicates whether the MUID identifier should be refreshed. on c.clarity.ms ### Leadfeeder Marketing Consent to service leadfeeder #### Usage We use Leadfeeder for Marketing. Read more about Leadfeeder #### Sharing data For more information, please read the Leadfeeder Privacy Statement. #### Marketing Name _lfa Expiration 2 years Function Identifies the visitor across visits so Leadfeeder can attribute page activity to a company. ### Miscellaneous Purpose pending investigation Consent to service miscellaneous #### Usage #### Sharing data Sharing of data is pending investigation #### Purpose pending investigation Name cmplz_functional Expiration 365 days Function Name cmplz_statistics Expiration 365 days Function Name cmplz_preferences Expiration 365 days Function Name cmplz_marketing Expiration 365 days Function ## 7. Consent When you visit our website for the first time, we will show you a pop-up with an explanation about cookies. As soon as you click on “Save preferences”, you consent to us using the categories of cookies and plug-ins you selected in the pop-up, as described in this Cookie Policy. You can disable the use of cookies via your browser, but please note that our website may no longer work properly. ### 7.1 Manage your consent settings You have loaded the Cookie Policy without javascript support. On AMP, you can use the manage consent button on the bottom of the page. ## 8. Enabling/disabling and deleting cookies You can use your internet browser to automatically or manually delete cookies. You can also specify that certain cookies may not be placed. Another option is to change the settings of your internet browser so that you receive a message each time a cookie is placed. For more information about these options, please refer to the instructions in the Help section of your browser. Please note that our website may not work properly if all cookies are disabled. If you do delete the cookies in your browser, they will be placed again after your consent when you visit our website again. ## 9. Your rights with respect to personal data You have the following rights with respect to your personal data: - You have the right to know why your personal data is needed, what will happen to it, and how long it will be retained for. - Right of access: You have the right to access your personal data that is known to us. - Right to rectification: you have the right to supplement, correct, have deleted or blocked your personal data whenever you wish. - If you give us your consent to process your data, you have the right to revoke that consent and to have your personal data deleted. - Right to transfer your data: you have the right to request all your personal data from the controller and transfer it in its entirety to another controller. - Right to object: you may object to the processing of your data. We comply with this, unless there are justified grounds for processing. To exercise these rights, please contact us. Please refer to the contact details at the bottom of this Cookie Policy. If you have a complaint about how we handle your data, we would like to hear from you, but you also have the right to submit a complaint to the supervisory authority (the Data Protection Authority). ## 10. Contact details For questions and/or comments about our Cookie Policy and this statement, please contact us by using the following contact details: Papers AG Baarerstrasse 43 6300 Zug Switzerland Website: https://obsidio.com Email: support@ex.comobsidio.com This Cookie Policy was synchronized with cookiedatabase.org on (not synced yet). ======================================== # FAQ URL: https://obsidio.com/faq/ FAQ # Frequently asked questions FAQ ## Everything you need to know. What is Obsidio?Obsidio is a Swiss DDoS simulation platform designed for critical infrastructure and companies. It provides controlled, realistic DDoS simulations that generate verifiable, audit-ready proof of operational resilience. Who needs DDoS simulations?Any organisation whose operations depend on online availability — banks, insurers, FMIs, energy and telecom providers, healthcare, government services, and large e-commerce. Anywhere FINMA, DORA, NIS2, or board-level resilience evidence is required. How does Obsidio differ from other testing providers?Traditional providers use a small number of cloud load generators. Obsidio orchestrates real, ethically sourced devices distributed worldwide, generating traffic that's indistinguishable from a genuine attack. Every result is cryptographically signed and independently verifiable. How do you ensure tests are safe and authorized?Every simulation requires explicit ownership verification — typically a DNS TXT record — before any traffic is generated. Tests run inside Trusted Execution Environments with full audit logging. No traffic can be launched against infrastructure you don't control. Will simulations disrupt our production systems?You define the intensity, duration, and scope. Most institutions run progressive simulations starting in a controlled window with conservative limits, then ramp up as confidence grows. Live metrics let you abort instantly. What evidence will we receive after a test?A cryptographically attested PDF report plus structured JSON data: full traffic profile, mitigation effectiveness, regulator-aligned control mapping, and tamper-proof signatures any auditor can verify. How does Obsidio support compliance?Reports map directly to FINMA operational resilience requirements, DORA testing obligations (Articles 24 and 25), and NIS2 incident-response expectations. Repeat the same scenario quarterly to show continuous improvement over time. Is Obsidio only for financial institutions?No — finance is our deepest expertise but the platform serves any critical-infrastructure operator. Healthcare, energy, telecom, government, SaaS, and large e-commerce all use Obsidio. Who develops and operates Obsidio?Obsidio is built and operated by Papers AG, a Swiss engineering firm specialising in regulated-industry security and compliance tooling. ======================================== # Imprint URL: https://obsidio.com/imprint/ LEGAL # Imprint ### Imprint Obsidioc/o Papers AGBaarerstrasse 436300 ZugSwitzerland Commercial Register: CHE-497.975.775 Company Form: Aktiengesellschaft (AG) Place of Jurisdiction: Zug, Switzerland Represented by: Alessandro de Carli, CEO #### Contact E-Mail: sales@obsidio.com Website: www.obsidio.com #### Regulatory Reference Obsidio provides resilience simulation services for financial institutions. While aligned with FINMA Circular 2023/1, Papers AG is not itself a financial intermediary and is not subject to FINMA licensing. #### Responsible for the content of this website (according to Art. 14 para. 1 of the Swiss Telecommunication Act): Papers AG #### Disclaimer The contents of this website are created with the utmost care. However, Papers AG assumes no liability for the accuracy, completeness, or timeliness of the information provided. References and links to third-party websites are outside our responsibility. Access and use of such websites are at the user’s own risk. #### Copyright All texts, images, graphics, and other content on this website are protected by copyright. Any use, reproduction, or distribution requires the prior written consent of Papers AG. Data Protection: Information on the collection and processing of personal data can be found in our Privacy Policy. ======================================== # Industries URL: https://obsidio.com/industries/ FOCUSED INDUSTRIES # DDoS simulations where it matters most. Obsidio is built for companies and institutions in critical sectors that require real-world DDoS simulations. Request a Demo ### Banks & Finance Swiss banks and securities dealers want to test their systems with real-world DDoS simulations — repeatable runs and audit-ready reports that help CISOs, compliance teams, and boards demonstrate regulatory alignment and operational continuity. ### Insurance & Reinsurance Insurers and reinsurers play a central role in Switzerland’s financial stability. Obsidio enables DDoS simulations that provide verifiable evidence of operational preparedness and continuity under pressure. ### Financial Market Infrastructure (FMIs) Stock exchanges, clearing houses, and payment systems are critical national infrastructure. Obsidio delivers simulations that mirror real-world attack dynamics, ensuring FMIs can withstand and recover from severe stress events. ### Energy & Telecom Beyond finance, energy and telecommunications providers face growing resilience expectations as national critical infrastructure. Obsidio supports scenario-based resilience testing that strengthens readiness for both cyber threats and regulatory scrutiny. Broader Applications ## Benefits for every level of your institution. DDoS simulations are increasingly relevant beyond finance. Obsidio supports organizations in other critical industries where uptime and continuity are essential. Request a Demo - HealthcareProtect sensitive patient data and ensure continuity of critical care services. - E-CommerceSafeguard online platforms against traffic surges and ensure uninterrupted business operations. - Cloud & SaaSProvide enterprise customers with verifiable evidence of service resilience and continuity. - Government & Public ServicesVerify DDoS resilience for essential services and safeguard public trust. ======================================== # Privacy Policy URL: https://obsidio.com/privacy-policy/ LEGAL # Privacy Policy This privacy policy explains how Papers AG (“we”, “us”) processes personal data when you use the Obsidio website and platform. It is provided to satisfy our obligations under the Swiss Federal Act on Data Protection (FADP) and, where applicable, the EU General Data Protection Regulation (GDPR). ## 1. Data controller Papers AG, Switzerland — sales@obsidio.com. ## 2. Data we collect - Contact data you submit via forms (name, email, organisation, message). - Account data when you use the platform (login identifiers, role, audit-log entries). - Technical data automatically logged on each request (IP address, user agent, timestamp). - Cookies required to operate the site and, with your consent, analytics cookies (see §5). ## 3. Purposes & legal basis - Responding to enquiries — necessary for the steps prior to entering a contract. - Providing the Obsidio platform — performance of contract. - Security, abuse prevention, audit logging — legitimate interest and legal obligation. - Analytics — your explicit consent. ## 4. Recipients Personal data is only shared with service providers that process it on our behalf (hosting, email, payment) under a data-processing agreement. We do not sell personal data. ## 5. Cookies & analytics The site uses strictly-necessary cookies. Optional analytics cookies are loaded only after you opt in via the cookie banner. You can withdraw consent at any time. ## 6. Retention We retain personal data only as long as necessary for the purposes set out above, or as required by law (e.g. ten-year retention for accounting records). ## 7. Your rights You have the right to access, rectify, delete, restrict, or port your personal data, and to object to processing. To exercise these rights, email sales@obsidio.com. You also have the right to lodge a complaint with the Swiss Federal Data Protection and Information Commissioner (FDPIC) or your local supervisory authority. ## 8. Updates This policy may be updated to reflect changes in our processing or in the law. The current version is always published on this page. ======================================== # Product URL: https://obsidio.com/product/ OUR PRODUCT # Swiss DDoS resilience testing. Obsidio simulates real-world pressure in a controlled, ethical, and verifiable way. Giving institutions compliance-grade evidence of resilience. Request a Demo Product Overview ## DDoS testing, simplified and structured. Obsidio provides institutions with a secure, enterprise-ready platform for resilience testing. With intuitive dashboards, configurable simulations, and audit-ready reporting, Obsidio turns regulatory requirements into measurable outcomes. Dashboard & Monitoring Simulation Types Audit-Ready Reports Security & Authorization How it works ## Four simple steps. STEP 1 ### Authorize Verify ownership with a DNS TXT entry. No traffic flows until you’ve explicitly authorized the test. STEP 2 ### Configure Select simulation type, scale, geography, and duration in a guided dashboard flow. STEP 3 ### Simulate Execute controlled simulations from 100k+ distributed devices. Watch live metrics in real time. STEP 4 ### Report Export compliance-ready results for auditors and boards, mapped to FINMA / DORA / NIS2. Simulation Types ## Realistic simulations that mirror real-world scenarios. Obsidio’s DDoS simulation catalog spans four categories, each replicating a different class of real-world and AI-driven attack faced by regulated institutions. It is continuously extended to keep pace with the evolving threat landscape. - Application-layer floods (L7)HTTP Flood, Goldeneye, Browser Flood and Apache Killer: high-volume, cache-busting and memory-exhaustion requests that stress the application path. - Slow attacksSlowloris and RUDY: hold connections or request bodies open to drain the connection pool at minimal bandwidth. - Connection exhaustionTLS Flood and TCP Connection Flood: burn TLS-handshake CPU or fill the connection table without touching the request layer. - Protocol-specific & scriptedDNS Flood and Puppeteer Script: stress the DNS tier over TCP, or drive scripted real-browser user journeys under concurrency. Our simulation catalog is continuously expanded and refined. As attackers evolve with AI-powered techniques, so does Obsidio — ensuring your resilience testing stays ahead of emerging threats and regulatory expectations. Dashboard & Monitoring ## Enterprise control at your fingertips. Obsidio’s dashboard makes simulations easy to manage and results simple to interpret. Institutions can schedule tests, track live progress, and export audit-ready reports. All in one interface designed for CISOs, compliance officers, and technical teams. Request a Demo - Credit balance & usage - Active simulation runs - Metrics: requests/sec, success rate, data transferred - Worker locations & status - Simulation progress overview Safety & Authorization ## Secure, ethical, and controlled. Every simulation is authorized and verifiable. Obsidio requires system ownership confirmation (e.g., DNS TXT entry) before any test is executed, ensuring no misuse is possible. All simulations run in Trusted Execution Environments (TEEs) with cryptographic attestation, providing tamper-proof assurance. - DNS verification - TEE security - Audit log - Ethical device sourcing ======================================== # Terms & Conditions URL: https://obsidio.com/terms-conditions/ LEGAL # Terms & Conditions These Terms govern access to and use of the Obsidio website and platform operated by Papers AG (“Obsidio”, “we”). By using the site or the platform you agree to these Terms. ## 1. Service description Obsidio provides a DDoS simulation platform for authorized resilience testing. Use of the platform is subject to a separate service agreement. ## 2. Authorized use only You may only simulate traffic against infrastructure you own or have written, verifiable authorization to test. We enforce this through DNS-TXT ownership verification and audit logging. Unauthorized use is strictly prohibited and may be reported to law enforcement. ## 3. Acceptable use - No use against critical infrastructure you do not control. - No reverse engineering, interference with platform security, or attempts to bypass authorization. - No use to harass, defraud, or harm third parties. ## 4. Intellectual property All software, documentation, branding, and reports are the property of Papers AG and its licensors. Reports we generate may be used internally and shared with your auditors and regulators. ## 5. Confidentiality Simulation parameters, results, and infrastructure information shared with us are treated as confidential and used only to deliver the service. ## 6. Limitation of liability To the extent permitted by law, our aggregate liability for any claim arising under or in connection with these Terms is limited to the fees paid for the service in the twelve months preceding the event giving rise to the claim. We are not liable for indirect or consequential damages. ## 7. Governing law & jurisdiction These Terms are governed by Swiss law. Place of jurisdiction is the registered seat of Papers AG. ## 8. Changes We may update these Terms from time to time. Material changes will be communicated to platform users. Continued use after a change constitutes acceptance. ======================================== # SYN Flood Attack: How It Works, and What It Cannot Test URL: https://obsidio.com/syn-flood-attack/ Published: 2026-08-06 A SYN flood attack never finishes a single connection. It sends the first packet of the TCP handshake, thousands of times a second, from source addresses that do not exist, then walks away. Each packet leaves the server holding a slot open for a client that will never answer. It is one of the oldest attacks on the internet and still one of the most common. Cloudflare’s 2025 Q2 DDoS threat report, published 15 July 2025, put SYN floods second among all network-layer vectors at 27% of attacks, down from 31% the quarter before. The short version - It attacks a queue, not a server. The target is the SYN backlog: the fixed-size table where the kernel remembers half-finished handshakes. Fill it and new connections are refused, no matter how much CPU or bandwidth is idle. - Spoofed source addresses are the entire trick. The server replies to an address that cannot answer, so the entry sits there until it times out. Real addresses would send a reset and free the slot immediately. - Modern defenses genuinely handle this one. SYN cookies are on by default in Linux, and edge scrubbing providers proxy the handshake before it reaches you. This is the vector the industry solved. - Which means it tells you almost nothing about full-connection capacity. A half-open connection costs a kernel table entry. A completed one costs a socket, a file descriptor, a conntrack entry and often a worker. - Obsidio does not run a SYN flood. The nearest simulation, TCP Connection Flood, completes real handshakes from real devices, which is the case your firewall and load balancer actually struggle with. This post is an explainer rather than part of our ten-part simulation series, because a SYN flood is not one of the ten types Obsidio runs, and the reason why is the most useful thing in here. For how the vector families relate to each other, see our overview of the types of DDoS attacks; for how to structure a first authorized run, start with the guide on how to test your DDoS protection. ## What is a SYN flood, mechanically? Every TCP connection opens with a three-step exchange. The client sends a SYN to say it wants to talk. The server replies with a SYN-ACK to say it is willing, and reserves memory for the coming connection. The client sends a final ACK, and the connection is established. Between step two and step three the connection is half-open. The server has committed state and is waiting. That state lives in a per-listener queue, usually called the SYN backlog, and on Linux each entry sits in SYN_RECV until the ACK arrives or the entry expires. A SYN flood sends step one and never sends step three. Each packet is 40-odd bytes and costs the sender nothing. Each one costs the server a backlog entry that will be held for as long as the kernel keeps retrying the SYN-ACK. On Linux the relevant knob is tcp_synack_retries, documented in the kernel’s networking sysctl reference with a default of 5, “which corresponds to 31 seconds till the last retransmission with the current initial RTO of 1 second”. Half a minute of free occupancy per packet, and the packets arrive by the thousand. When the backlog is full, further SYN packets are dropped. From the outside the site is simply unreachable. From the inside, CPU is low, bandwidth is low, the application logs are quiet, and nothing is broken except the ability to accept a new connection. Picture a receptionist with a desk that holds twenty message slips. Twenty callers each say “hold on, I’ll be right back with my name” and never return. The receptionist is not busy; the desk is just full, and the twenty-first caller is told to go away. ## Why does source-address spoofing matter so much? The attack depends on the server’s reply going nowhere. RFC 4987, “TCP SYN Flooding Attacks and Common Mitigations”, published in August 2007, is blunt about it: “For an effective attack, it is important that the spoofed IP addresses be unresponsive to the SYN-ACK segments.” If the forged address belongs to a live host, that host receives an unsolicited SYN-ACK, does not recognise it, and sends a reset. The reset frees the backlog entry instantly and the attack collapses. So attackers forge addresses that are dark: unallocated space, or ranges with nothing listening. That has three consequences worth holding onto. - Per-source rate limiting has nothing to count. Every packet appears to come from a different address, and none of those addresses will ever send a second packet. - Blocklisting is useless and dangerous. The addresses in your logs did not send the traffic. Blocking them punishes uninvolved networks, sometimes including your own users. - The attack requires the ability to forge packets at all. That is a property of the attacker’s upstream network, not of your defenses. Which is why the oldest structural fix is not on the victim’s side. RFC 2827, better known as BCP 38, published in May 2000, asks every network to filter outbound traffic so that it can only carry source addresses from the ranges that network actually announces. Adoption is partial after a quarter of a century. CAIDA’s Spoofer project, which continuously measures source-address validation from volunteer vantage points, showed 233 of 1,430 tested IPv4 blocks as spoofable when we checked its summary page on 29 July 2026, roughly one in six once NAT cases are excluded. The history is worth a line. CERT Advisory CA-1996-21 documented SYN flooding and IP spoofing in September 1996, prompted partly by an attack that took down the mail servers of New York ISP Panix. Thirty years on, Cloudflare’s 2025 Q3 report of 3 December 2025 still listed SYN floods third among network-layer vectors, behind UDP and DNS floods and ahead of ICMP. Together those four made up just over half of all network-layer attacks in a quarter where Cloudflare mitigated 8.3 million attacks overall. ## Which of your controls should have caught this? It is worth walking the whole chain a connection passes through. For most attacks in this series the answer is uncomfortable. For this one it is mostly reassuring, and saying so plainly matters more than making every control look broken. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. This is the vector these services were built for. The scrubbing centre answers the handshake itself and forwards only connections a real client completed. It holds, provided your traffic routes through it and your origin is not reachable directly. - Firewall and WAF. Pull the two apart. A WAF inspects requests and no request is ever sent, so it sees nothing. A stateful firewall does see it, and can become the bottleneck itself if its state table is smaller than the server’s backlog. - Rate limiting. Keys on source address or on requests. The sources are forged and never repeat, and no request arrives to be counted. - Bot detection and challenges. A challenge needs a session to challenge. The connection never opens. - CDN cache. Nothing cacheable is in play. It matters only because a CDN keeps your origin address off the path, and that is the part which decides this. Zone 2 What takes the hit? - Load balancer or reverse proxy. Whatever terminates TCP first owns this problem. If the flood reaches you at all, the accept queue and connection state here are what fill up. - Connection layer. The SYN backlog is the actual target. SYN cookies turn a memory-exhaustion problem into a cryptographic-CPU one, which is a much better trade but not a free one. - Web server. The kernel handles the half-open queue. The server process is never handed a connection, so worker slots and request handling stay untouched. - Application and database. Never reached. No request is ever completed, so no query is ever issued. - Auto-scaling. Watches request rate, latency and CPU. Half-open connections are not requests, so the signals stay flat while the service is unreachable. Zone 3 Would you find out? - Dashboards. Packets per second and new connections per second do move sharply, unlike a slow attack. Whether you notice depends on whether anyone graphs TCP connection state rather than only HTTP metrics. - A check from outside your network. Still the only thing that reliably tells you real users are being refused, since every internal metric can look calm. - Logging and your SIEM. No access-log lines, because no request completes. Firewall and flow logs do carry it, if you collect and retain them. - Alerting. Fires if you have a threshold on connection state or packet rate. Most alert sets watch error rate and response time, which do not move here. - On-call. Usually paged eventually, by a customer or by your scrubbing provider, rather than by your own monitoring. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. Compare that grid with the one on the Slowloris post and the verdicts largely invert. Volume-based scrubbing is blind to a slow attack and decisive against a SYN flood. That inversion is the argument for coverage across vector families. ## How do you mitigate a SYN flood? Four controls carry almost all of the weight, and three of them are already on in a default modern deployment. - SYN cookies. Instead of storing state for a half-open connection, the server encodes what it needs into the sequence number of its own SYN-ACK and forgets the connection. If a legitimate ACK comes back, the state is reconstructed from the number the client echoes. RFC 4987 also gives the limits: incompatible with some TCP options, and no handling of data piggybacked on the SYN. On Linux, tcp_syncookies defaults to 1, which the kernel documentation describes as sending cookies “when the syn backlog queue of a socket overflows”, so normal connections are unaffected. - Backlog sizing. tcp_max_syn_backlog is a per-listener limit on remembered SYN_RECV requests. The kernel docs give a minimum of 128 on low-memory machines, scaling with available memory. Raising it buys headroom, and only headroom: a large queue fills more slowly than a small one and still fills. RFC 4987’s note that typical defaults then ranged “from a half-dozen to several dozen” is a good reminder of how much this has already improved. - Faster expiry of half-open state. Lowering tcp_synack_retries shortens how long each unanswered handshake occupies a slot. The cost is real: clients on genuinely lossy mobile networks sometimes need those retries, so this is a trade rather than a win. - SYN proxying at the edge. A scrubbing service or capable appliance completes the handshake on your behalf and forwards only connections that a client actually finished. This is the strongest control, because the flood terminates on infrastructure sized for it. It also has the same precondition as every other edge defense: an origin address that is not reachable around it. That last precondition is where real deployments fail. A protected hostname in front of an origin whose address still answers on port 443 is not protected, and nothing in a configuration review makes that visible. ## Why is a SYN flood attack a poor test of connection capacity? Here is the part that matters if you are planning a resilience test rather than reading a glossary. A SYN flood measures one thing: whether the first device that terminates TCP can survive being asked to remember handshakes that never complete. In 2026 the answer is usually yes, because SYN cookies exist and edge proxying works. Completed connections are a different problem. A fully established, idle TCP connection consumes a socket and a file descriptor on the server, an entry in the connection-tracking table of every stateful device on the path, and a slot against any per-IP or global connection limit. SYN cookies do nothing about any of that, because from the stack’s point of view these connections are entirely legitimate. They were opened by real hosts that answered honestly. This is why Obsidio’s catalogue includes TCP Connection Flood and not a SYN flood. The simulation opens raw TCP connections, completes the handshake, and holds each socket idle for up to the configured timeout before recycling it, with a default hold of ten minutes and up to a hundred sockets per worker. Because the traffic comes from 100,000+ globally distributed real devices with real routable addresses, per-IP connection caps get tested against genuine source diversity rather than against a handful of datacenter hosts, and the conntrack tables on every device in the path fill with entries that no cookie trick can shed. A TLS Flood goes one layer further again, completing the TLS negotiation and paying the server roughly fifteen times the client’s crypto cost before abandoning the socket. Half-open, fully open and fully negotiated test three different resources. ## What you can check yourself, and what it will get wrong Two of these questions you can answer today without any traffic, and it is worth knowing which. Read the configuration. Confirm tcp_syncookies is enabled, look at your actual backlog and retry values, and check the state-table limits on every stateful device in the path, not just the server. This tells you the settings exist. It does not tell you which limit is smallest, and the smallest one is the one that decides the outcome. Confirm your origin is unreachable directly. If an edge service is the control you are relying on, verify from outside that the origin address does not answer. This is a genuine test of a genuine dependency and it needs no attack traffic. Test alert routing on its own. Fire a synthetic alert at the on-call rotation and see whether anyone acts. That verifies the plumbing, and says nothing about whether a threshold exists on TCP connection state, which is the signal that would have moved. What a small self-run test gets wrong is more interesting. Traffic from one or two hosts is caught by per-source controls immediately, so the front of the chain appears to work perfectly. That conclusion is backwards: those are precisely the controls that behave differently against real source diversity. ## How Obsidio tests the connection layer Obsidio runs connection-exhaustion simulations as controlled, authorized tests against infrastructure the customer owns. Domain ownership is verified by DNS TXT record before any traffic flows. Per the platform FAQ, most institutions start in a controlled window with conservative limits and ramp up as confidence grows, and live metrics let a run be aborted instantly. For a TCP Connection Flood the numbers to watch are not the request-rate graph, which counts socket opens rather than throughput and will look trivially small while the test is succeeding. Watch active and peak concurrent connections, and watch them alongside the connection-table utilisation on your own load balancer and firewall. That pairing is what tells you which limit is binding. Two answers stay on your side of the line. Obsidio can report what your edge controls did and how many connections were held, because that is observable from outside. Whether your SIEM recorded anything and whether anyone was paged live only in your own consoles, so somebody has to be watching them during the window. Strength is proven, not promised. A SYN flood asks whether your kernel can forget a handshake. The harder question, and the one Obsidio actually measures, is what happens when a hundred thousand real devices complete one and refuse to hang up. ## Where this fits in a testing programme Treat the classic SYN flood as a control you verify rather than a scenario you rehearse. Check that cookies are on, that your edge proxies handshakes, that your origin is not reachable around it, and move on. Cloudflare’s 2025 Q4 report of 5 February 2026 counted 47.1 million DDoS attacks across the year, network-layer attacks rising to 34.4 million from 11.4 million in 2024, so the volume is real. The mitigation is also mature, and a test window spent here buys little. The exhaustion tests worth a window are the ones that use legitimate connections, because no cookie, no challenge and no reputation list can distinguish them from your customers. Those are the runs where a per-IP cap, a conntrack limit or a load balancer’s session table turns out to be the number that decides whether your service stays up. For regulated institutions the run also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports generated inside Trusted Execution Environments and mapped to FINMA, DORA and NIS2, so the outcome of a test is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized connection-exhaustion simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # DORA Compliance: What the Testing Pillar Actually Requires URL: https://obsidio.com/dora-compliance/ Published: 2026-08-04 The Digital Operational Resilience Act has applied since 17 January 2025, and it is a regulation, not a directive. Regulation (EU) 2022/2554 binds financial entities in every EU member state directly, with no national transposition to wait for and no room to read it as guidance. Most of DORA can be satisfied on paper: policies, registers, contract clauses, reporting templates. One pillar cannot. Article 24(6) requires tests to actually run, at least yearly, on every ICT system supporting a critical or important function. That is the part of DORA compliance a binder full of policies does not cover, and it is the part this guide treats in depth. The short version - DORA applies since 17 January 2025. Regulation (EU) 2022/2554, Article 64. Directly binding in every EU member state. - Scope is wide. Article 2(1) lists 21 categories of entity, from credit institutions to crowdfunding service providers, and adds ICT third-party service providers on top. - Five pillars, and one of them is operational. ICT risk management, incident reporting, resilience testing, ICT third-party risk, information sharing. Testing (Chapter IV, Articles 24 to 27) is the pillar you cannot document your way through. - Testing is yearly. TLPT is every three years. Article 24(6) requires appropriate tests at least yearly on all ICT systems and applications supporting critical or important functions. Entities designated by their supervisor must add threat-led penetration testing at least every three years under Article 26. - Evidence is the deliverable. DORA expects a documented programme, classified findings and validated remediation. A test that leaves no verifiable record does very little for you in a supervisory review. ## What is the Digital Operational Resilience Act? DORA is the EU’s response to a plain observation: a financial institution can be perfectly solvent and still be down. Capital buffers say nothing about whether the e-banking front end survives a traffic surge or whether a core provider’s outage cascades through the sector. The regulation was adopted on 14 December 2022, and Article 64 sets the application date: it applies from 17 January 2025. Since that date, supervisors can examine any in-scope entity against the full set of DORA requirements. Article 3(1) defines digital operational resilience around a financial entity’s ability to build, assure and review its own operational integrity. The verb “review” does the real work in that definition. DORA does not ask you to be resilient. It asks you to keep checking that you are, and to keep records of the checking. ## Who does DORA apply to? Article 2(1) lists twenty-one categories of entity, points (a) through (u). Credit institutions, payment institutions, e-money institutions and investment firms are the obvious ones. The list continues through crypto-asset service providers, central counterparties, trading venues, fund managers, insurance and reinsurance undertakings, occupational pension institutions, credit rating agencies, crowdfunding service providers and securitisation repositories. Article 2(2) then does something worth noticing: points (a) to (t) are collectively defined as “financial entities”, while point (u), ICT third-party service providers, sits in scope separately. Providers designated as critical come under a dedicated EU oversight regime, which means a cloud or software vendor serving the financial sector can face supervisory attention without being a financial firm at all. Microenterprises get proportionate treatment. Several testing obligations in Chapter IV open with “financial entities, other than microenterprises”, and Article 25(3) lets microenterprises combine a risk-based approach with strategic planning of their testing instead. Swiss institutions are not directly in scope. Swiss groups still meet DORA through their EU subsidiaries and branches, and Swiss vendors meet it through the third-party pillar the moment an EU financial entity depends on them. More on the Swiss position below. ## What are the five pillars of DORA? The DORA requirements fall into five blocks, usually called the five pillars: - ICT risk management. A documented risk-management framework owned by the management body: identify, protect, detect, respond, recover, learn. - ICT-related incident management and reporting. Classify incidents against common criteria and report major ones to the competent authority on fixed timelines. - Digital operational resilience testing. Chapter IV, Articles 24 to 27. A standing testing programme, yearly tests on systems behind critical or important functions, and advanced threat-led testing for designated entities. - ICT third-party risk management. Contract requirements, a register of all ICT service arrangements, concentration-risk analysis, and EU-level oversight of critical providers. - Information sharing. A legal basis for financial entities to exchange cyber threat intelligence within trusted communities, voluntarily. Four of the five are mostly governance work. They produce documents, registers and reporting lines, and a capable compliance function can drive them. The testing pillar is different in kind. It requires something to happen to production-relevant systems on a schedule, and it produces findings that someone must fix and then prove fixed. ## What does DORA require for resilience testing? Article 24 sets the frame. Financial entities other than microenterprises must establish, maintain and review a sound and comprehensive digital operational resilience testing programme, as an integral part of the ICT risk-management framework. The purpose is stated plainly: assess preparedness, identify weaknesses and gaps, and implement corrective measures promptly. The article then adds four conditions that decide whether a programme survives supervisory scrutiny: - Range. The programme must include a range of assessments, tests, methodologies, practices and tools, applied as Articles 25 and 26 describe (Article 24(2)). A single annual pentest does not make a programme. - Risk basis. Testing follows a risk-based approach that accounts for the evolving ICT risk picture and the criticality of the assets involved (Article 24(3)). - Independence. Tests are undertaken by independent parties, internal or external; internal testers need conflict-of-interest safeguards (Article 24(4)). - Remediation. Entities need procedures to prioritise, classify and remedy every issue a test reveals, and internal validation that weaknesses are fully addressed (Article 24(5)). Findings that sit unresolved in a report are their own compliance failure. Then comes the sentence that drives most testing calendars in the EU financial sector. Article 24(6): financial entities, other than microenterprises, shall ensure, at least yearly, that appropriate tests are conducted on all ICT systems and applications supporting critical or important functions. Not a sample. All of them, every year. Article 25(1) says what counts as testing, and the list is broad: vulnerability assessments and scans, open source analyses, network security assessments, gap analyses, physical security reviews, questionnaires and scanning software solutions, source code reviews where feasible, scenario-based tests, compatibility testing, performance testing, end-to-end testing and penetration testing. The list is introduced with “such as”, so it is illustrative rather than exhaustive, but it makes one thing clear: DORA’s idea of testing goes well beyond an annual penetration test. Availability under load belongs in it just as much as exploitable code does. One sharper rule sits in Article 25(2): central securities depositories and central counterparties must perform vulnerability assessments before any deployment or redeployment of applications, infrastructure components or ICT services supporting critical or important functions. For market infrastructure, testing gates the release process itself. ## What is threat-led penetration testing under DORA? Article 3(17) defines TLPT as a framework that mimics the tactics, techniques and procedures of real-life threat actors. In practice it is a supervised red-team exercise built on live threat intelligence, and DORA turns it from a voluntary maturity exercise into a legal obligation for part of the sector. Article 26 sets the terms. Designated financial entities must carry out advanced testing by means of TLPT at least every three years, and the competent authority can adjust that frequency up or down based on the entity’s risk profile. Supervisors decide who is in, based on impact-related factors, financial stability concerns and the entity’s ICT risk profile and maturity. TLPT is not a universal DORA requirement; it is targeted at the entities whose failure would matter most. The test itself is deliberately uncomfortable. It must cover several or all critical or important functions and be performed on live production systems. Where those functions run on outsourced ICT, the third-party providers are included in scope, with the financial entity keeping full responsibility; where direct participation would endanger service quality or confidentiality, pooled TLPT across several financial entities is the fallback. The regulatory standards for how these tests run were developed by the European Supervisory Authorities in accordance with TIBER-EU, the ECB-originated framework for threat-intelligence-based red teaming. Article 27 governs who may test. Testers need demonstrated expertise in threat intelligence, penetration testing and red-team operations, certification or adherence to formal codes of conduct, independent assurance on their own risk management, and professional indemnity insurance. Internal testers are allowed, but Article 27 requires the competent authority’s approval and an external threat intelligence provider, and Article 26(8) adds that external testers must be contracted every three tests. Significant credit institutions must use external testers exclusively. After the test, the authority issues an attestation confirming it was performed in accordance with the requirements, which other EU supervisors then recognise. That detail says a lot about DORA’s mindset: the output of a test is a verifiable artifact that travels between regulators, not a private slide deck. ## What evidence do regulators expect? Read Articles 24 to 27 again with an auditor’s eye and a pattern appears. The programme must be documented. Findings must be classified and prioritised. Remediation must be validated, not asserted. TLPT results come with a formal attestation precisely so that a second authority can rely on them without re-running the exercise. So the practical question for a compliance officer is not “did we test?” but “can we prove what we tested, what we found, and what we fixed?” A screenshot of a monitoring dashboard answers none of that. It has no independent origin and no tamper protection, and it says nothing about how the test was run. Evidence that stands up in a supervisory review is generated by the test itself, by a party with no stake in the result, in a form that cannot be quietly edited afterwards. That standard is worth applying to every vendor in your testing programme, whatever they test. Ask how their report proves the test happened as described, and what stops anyone from touching the numbers between the run and the filing. ## Where does DDoS resilience testing fit into DORA compliance? Availability is the resilience property that denial-of-service attacks target, and the exposure keeps growing. Cloudflare’s 2026 Threat Report, published in March 2026, counted 47.1 million DDoS attacks mitigated across its network in 2025, a 121 percent increase over the previous year. The same provider’s Q1 2025 DDoS threat report had already logged 20.5 million attacks blocked in a single quarter, a 358 percent increase year over year, with banking and financial services climbing its ranking of most-attacked sectors. For a bank, the systems those attacks aim at are the ones Article 24(6) names: the e-banking portal, the payment gateway, the trading front end. Systems supporting critical or important functions, due for appropriate tests at least yearly. Look back at the Article 25(1) list and the fit is direct. A controlled DDoS simulation against your own infrastructure is a scenario-based test, a performance test and an end-to-end test of the availability path, all at once. It answers the question none of the paper exercises can: does the defence stack you paid for actually hold when realistic attack traffic arrives? Our guide on how to test your DDoS protection covers how to structure that first run, and our DDoS stress test explainer covers what a controlled run looks like in practice. Obsidio runs exactly this class of test, built for the constraints regulated entities operate under. Domain ownership is verified by DNS TXT record before any traffic flows, so no simulation can ever touch infrastructure you do not control. Runs ramp up gradually and can be aborted live. Traffic comes from 100,000+ globally distributed real devices rather than a handful of datacenter IPs, which is what makes the result meaningful: defences that key on source concentration behave very differently against one machine than against a realistic distributed pattern. Ten simulation types cover application-layer floods, slow attacks, connection exhaustion and protocol-specific vectors, so the yearly programme can rotate scenarios instead of repeating one. The evidence side is where the DORA fit becomes concrete. Obsidio produces cryptographically attested, tamper-evident reports generated inside Trusted Execution Environments and mapped to DORA, FINMA and NIS2. The report of a run is filing-grade: an independent, verifiable record of what was tested, when, at what intensity and with what outcome, which is precisely the shape of evidence Articles 24(5) and 24(6) assume. Retesting after remediation then closes the validation loop the regulation asks for. Strength is proven, not promised. DORA turned that from a principle into a legal test: since 17 January 2025, the question a supervisor asks is not whether you believe your critical systems are resilient, but what evidence you can put on the table. ## What about Swiss institutions? Switzerland is not an EU member state, so DORA does not apply to Swiss entities directly. The Swiss regulator got there on its own track: FINMA’s Circular 2023/1 on operational risks and resilience for banks, in force since 1 January 2024, embeds the Basel Committee’s operational resilience principles, with transition periods for the resilience provisions running until the start of 2026. The supervisory expectation on both sides of the border now points the same way: identify critical functions, test the systems behind them, and evidence the results. The EU’s NIS2 Directive (Directive (EU) 2022/2555) rounds out the picture. Member states had to transpose it by 17 October 2024, and it covers essential and important sectors well beyond finance. For financial entities, DORA takes precedence as the more specific regime, so a bank’s ICT risk and testing obligations run through DORA rather than NIS2, while group companies outside the financial perimeter can still be caught by NIS2 itself. For a Swiss institution with EU operations, that is three regimes with one common denominator. A resilience test worth running should produce evidence portable across all of them, which is why Obsidio maps every attested report to FINMA, DORA and NIS2 at once rather than to a single framework. ## How do you make a testing programme DORA-ready? The sequencing follows from the articles themselves: - Map your critical or important functions first. Article 24(6) is scoped to the systems supporting them, so the function map decides what must be tested at all. - Inventory those systems, including the ones running at third parties. - Build a yearly calendar that draws on the Article 25(1) range rather than repeating one test type, and put availability scenarios on it alongside vulnerability work. - Route every finding into a tracked remediation process with validation at the end, because Article 24(5) treats an unremedied finding as an open obligation. - Plan the TLPT cycle early if you are in the population your supervisor designates. Article 27 makes qualified testers a gating requirement, and the three-year clock needs tester contracts in place. To put an authorized DDoS resilience test on that calendar, with evidence you can file rather than vouch for, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # Types of DDoS Attacks: The Complete Taxonomy URL: https://obsidio.com/types-of-ddos-attacks/ Published: 2026-08-02 Two events can both be filed as “DDoS” and have almost nothing in common. One saturates an uplink with terabits per second of spoofed UDP packets. The other holds a few hundred sockets open from one laptop and sends a few kilobytes a minute. The control that stops the first cannot see the second at all. That is why the taxonomy is worth getting right. Sorting attacks by the way they cause failure, rather than by name, tells you which part of your stack decides each outcome and which whole class you have never put under load. The short version - There are four failure classes, not one long list of names. Volumetric attacks exhaust bandwidth, protocol and state-exhaustion attacks exhaust connection tables, application-layer attacks exhaust the work your application can do, and slow attacks exhaust patience by never finishing. - Most named attacks are variations on a handful of mechanisms. Once you know which resource a technique consumes, you know which control is supposed to catch it, and roughly what your logs will look like afterwards. - Count and impact are different questions. Cloudflare’s 2025 Q4 DDoS threat report put network-layer attacks at 78% of all attacks it mitigated that quarter, yet the attack that takes a bank offline can be a small application-layer one nobody graphed. - Not every class can be tested honestly. Reflection and amplification depend on forging source addresses and abusing servers belonging to strangers, so no legitimate testing platform will reproduce them against you. - Obsidio runs ten simulation types covering three of the four classes. Application-layer, slow and connection exhaustion are all directly testable, plus DNS resolver load. Spoofed volumetric floods are not, and we say so rather than implying otherwise. This post is the map. Each of the ten simulation types Obsidio runs has its own detailed post covering mechanics, mitigation and how to test it, and they are listed below. For how to structure a first run across the classes, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## How are DDoS attacks classified? The industry standard split follows the OSI layers, and it is useful as far as it goes. Volumetric attacks work at layer 3 and 4 and try to fill a pipe. Protocol or state-exhaustion attacks also sit at layer 3 and 4 but aim at a table rather than a link. Application-layer attacks work at layer 7, where every request costs the target real computation. Slow attacks are technically layer 7 as well, and are often filed under the application-layer heading. In operational terms that is a mistake. An application-layer flood is loud, and every rate-based control has something to trigger on. A slow attack sends less traffic than a single real user and defeats those controls by staying below every threshold they measure. Treating them as one class is how teams end up believing a flood test covered both. So four classes: volumetric, protocol and state exhaustion, application-layer, and slow. Obsidio’s public product page groups its ten simulation types into four platform categories that map onto this closely, splitting off DNS and scripted browser work into their own group rather than treating volumetric floods as testable. Note that both fours are counts of groupings. The catalogue itself is ten. ## Volumetric attacks: can your pipe absorb the traffic? A volumetric attack does not care what your application does. It sends more bits per second than your uplink, your edge router or your scrubbing contract can carry, and everything behind that bottleneck becomes unreachable whether or not it is healthy. Success is measured in gigabits or terabits per second. The main techniques in this class: - UDP flood. Raw UDP datagrams sent to random or fixed ports with no connection to establish and no state to keep on the sender’s side. Cheap for the attacker, which is why it dominates: Cloudflare’s 2025 Q3 DDoS threat report named UDP floods the top network-layer vector that quarter, up 231% quarter over quarter. - ICMP flood. The classic ping flood. Fourth most common network-layer vector in the same Cloudflare quarter, and largely a solved problem at any competent edge. - Reflection and amplification. The attacker sends small queries to open third-party servers with your address forged as the source, so the servers send you the much larger replies. DNS, NTP, SSDP, CharGEN and memcached have all been abused this way. The amplification ratios are what make it dangerous: Cloudflare’s 27 February 2018 write-up of the memcached attacks documented a 15 byte request producing a 750 kilobyte response, an amplification factor of 51,200 times. - Carpet bombing. Rather than one target address, the traffic is spread thinly across an entire prefix so no single host crosses a detection threshold while the aggregate still saturates the link. Scale in this class has moved fast. Cloudflare’s 2025 Q4 report describes a record 31.4 terabits per second attack that lasted 35 seconds, and NETSCOUT’s DDoS Threat Intelligence Report for the second half of 2025 counted more than 8 million DDoS attacks across 203 countries in that period alone. What decides the outcome. Not your servers. Upstream capacity, your transit providers, and whether your scrubbing provider detects and diverts fast enough. Anything you configure on the host is downstream of the bottleneck and therefore irrelevant to this class. Testability, honestly. Obsidio does not simulate spoofed-source or reflection attacks, and neither should anyone else. Forging source addresses and pointing third-party servers at your network abuses infrastructure that belongs to other people, which cannot be authorized by you and is not something we will build. What is worth testing is the detection and diversion path: whether your provider notices, how long the divert takes, and whether anyone on your side is told. Parts of that are answerable with authorized application-layer load, and the rest belongs in a tabletop exercise with your provider. ## Protocol and state-exhaustion attacks: how many connections can you hold? This class does not try to fill your bandwidth. It fills a table. Every established or half-established connection occupies a slot somewhere: a kernel socket, a conntrack entry, a file descriptor, a load balancer session, a TLS session cache. Those slots are finite and usually much smaller than people assume. - SYN flood. Sends the first packet of the TCP handshake and never completes it, filling the backlog queue with half-open connections. Still the reference attack for this class after three decades. It has its own post: how a SYN flood works and how to test for it. - ACK, RST and TCP flag floods. Packets that do not belong to any known session, forcing the target to look each one up in its state table and decide what to do. The lookup is the cost. - TCP connection flood. Fully established connections, opened and held idle. No spoofing, because the handshake has to complete. This is a different failure from a SYN flood and defeats a different set of controls, which is why TCP Connection Flood is a separate simulation type. - TLS handshake flood. Completes the full handshake, letting the server pay the asymmetric-crypto cost, then abandons the connection. Server-side CPU cost per handshake runs roughly fifteen times the client side, so the asymmetry favours the attacker heavily. See TLS Flood. - Fragmentation attacks. Malformed or incomplete IP fragments that force the target to hold reassembly buffers for fragments that never arrive. SYN floods sat third among network-layer vectors in Cloudflare’s 2025 Q3 report, behind UDP and DNS floods, with those four vectors together accounting for just over half of all network-layer attacks that quarter. What decides the outcome. SYN cookies, backlog and conntrack sizing, per-source connection limits, and whether your load balancer terminates connections or passes them through. A CDN in front helps only if your origin address cannot be reached directly. Testability. Partly. Obsidio’s TCP Connection Flood and TLS Flood test the fully-established end of this class directly and thoroughly, from real distributed devices, so per-source connection caps face the source diversity that a real attack would bring. Half-open SYN floods are a different matter: they require source-address spoofing, so they are outside what an authorized test can reproduce. The SYN flood post covers what you can verify by other means. ## Application-layer attacks: how much work does one request cost you? At layer 7 the economics change. Every request is valid, arrives over a completed TCP and TLS handshake, and asks the target to do something: run a query, render a page, check a session. A few thousand requests per second aimed at a search endpoint can be far more damaging than a hundred times that volume of packets aimed at a router. These attacks are also harder to distinguish from customers, because structurally they are customers. Cloudflare’s 2025 Q3 report found nearly 70% of HTTP DDoS attacks came from botnets it already recognised, and around 20% came from fake or headless browsers or carried suspicious HTTP attributes. The remainder looked like nothing in particular. - HTTP flood. High-concurrency well-formed requests against a real endpoint, targeting the request-processing path rather than the network. See HTTP Flood. - Cache-busting floods. The same idea with randomized query strings and rotating browser-like headers, so every request misses the CDN cache and reaches origin. GoldenEye is this pattern. - Real-browser floods. Traffic from actual browser engines that execute your JavaScript and fetch every sub-resource, which is what makes bot-detection challenges so much less decisive than their datasheets suggest. See Browser Flood. - Expensive-request exploits. Requests crafted so the server does disproportionate work per request. Apache Killer is the canonical case, using overlapping Range headers against CVE-2011-3192 so a small request forces the server to allocate the response body many times over. - Protocol-abuse floods. HTTP/2 Rapid Reset (CVE-2023-44487), disclosed jointly by Cloudflare, Google and AWS in October 2023, opened and immediately cancelled streams to make the server do the work while the client did almost none. Cloudflare reported mitigating 201 million requests per second from a botnet of roughly 20,000 machines. - Targeted endpoint abuse. Login pages, password resets, search, cart and checkout, report generation, any API path that writes to a database. Low request rates, high cost per request. What decides the outcome. Rate limiting granularity, bot management, WAF rules, and how far the damage travels once a request is accepted. Application-layer attacks reach the parts of your system a network attack never touches, which usually means the database connection pool. Testability. Fully. Four of Obsidio’s ten simulation types live in this class, and Puppeteer Script covers the adjacent question of how a real user journey behaves while the system is under pressure. ## Slow attacks: what happens when the traffic never arrives? The fourth class inverts every assumption the other three rely on. A slow attack sends as little as possible, as slowly as possible, for as long as possible. Rate-based defenses have nothing to count, volumetric detection sees no spike, and the request rate graph stays flat while the service is already unreachable. - Slow headers. Send the request line, then trickle header lines forever and never send the terminator. The server stays parked in “reading request headers” state. See Slowloris, whose original tool was released on 17 June 2009 and still works, because the behaviour it exploits is not a bug. - Slow body. Advertise a truthful Content-Length on a POST, then send the body one byte at a time. Headers are complete, so a header-read timeout does not fire. See RUDY. - Slow read. Send a perfectly valid request and then stop reading the response, so your receive buffer fills and the server’s send buffer backs up. Nothing about the request is wrong. The attack is on the read side. - Connection churn. Valid keep-alive requests that sit idle and then reset abruptly, stressing teardown and connection accounting rather than capacity. What decides the outcome. Timeouts with a minimum transfer rate rather than a bare deadline, per-source connection limits, and whether your reverse proxy fully buffers requests before forwarding them. This class is settled by configuration values in files, which is exactly why it drifts. Testability. Fully, and this is the class most worth testing, because a configuration review tells you the setting exists and nothing about whether the pool holds under real concurrency. ## Which types can you actually test? Being clear about this is more useful than a longer capability list. Across the four classes: - Directly testable with Obsidio’s ten simulation types. Application-layer floods including cache-busting and real-browser traffic, memory-amplification request exploits, both slow-attack directions, established-connection exhaustion, TLS handshake load, DNS resolver load over TCP, and scripted user journeys under concurrency. - Testable in part. Detection and escalation for volumetric events. You cannot authorize a spoofed terabit flood, but you can find out whether your monitoring and your on-call rotation react to a genuine distributed traffic event at all. Whether anyone was paged is a real finding regardless of which class produced the traffic. - Not testable, by design. Reflection and amplification off third-party servers, and any spoofed-source attack including SYN floods. These need infrastructure you do not own and address forging you cannot consent to on the internet’s behalf. Verify these through configuration review, your provider’s own drill programme, and network-level filtering checks. Any vendor claiming to test the whole taxonomy is either being loose with words or doing something you should not want your name attached to. ## Why does the class matter more than the name? Attack names come and go. The classes do not, because they describe which finite resource runs out, and that set is small. The practical consequence is coverage. A team that runs one volumetric test a year has measured a single bottleneck. Their timeouts, their connection limits and their per-endpoint rate limiting remain entirely unmeasured, and each of those is a different way to be offline. Cloudflare’s 2025 Q3 report also noted that 71% of HTTP DDoS attacks and 89% of network-layer attacks end in under ten minutes, so the question is rarely whether you would survive a long siege. It is whether anything at all happens automatically in the first two minutes. Class membership predicts your blind spots too. A volumetric attack is obvious in every graph you own, and settled entirely by someone else. An application-layer flood generates so much alerting that the signal disappears inside it. Connection exhaustion shows up as a connection count that nobody has a dashboard for, and a slow attack produces no graph movement at all, often not even an access-log line. Those are four different detection failures, and fixing one does nothing for the others. Strength is proven, not promised. Knowing the taxonomy tells you what could happen to you. Only a controlled, authorized simulation against your own infrastructure tells you what does. ## Where should you start if a class has never been tested? Pick the class where you have the least evidence, not the one that sounds most frightening. For most organisations that is the slow class, followed by established-connection exhaustion, because both are decided by settings nobody has looked at since installation. Then run something real against it. Obsidio runs each of its ten simulation types as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually from conservative limits, and live metrics let you abort instantly. Load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, which is the difference between testing a per-source rate limit and testing whether it means anything against source diversity. Our post on running a DDoS stress test covers the sequencing, and the pillar guide covers scoping a first programme. Banking and financial services ranked fourth among the most-attacked industries in Cloudflare’s 2025 Q3 report, and for regulated institutions the result of a run has to be filable rather than screenshotted. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so a test leaves an artifact an auditor can check independently. To scope authorized simulations across the classes that apply to your stack, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # DDoS Stress Test: What It Is, When It’s Legal, and How a Real One Runs URL: https://obsidio.com/ddos-stress-test/ Published: 2026-07-31 Most organizations that own DDoS protection have never watched it handle an attack. The appliance was installed, the scrubbing contract was signed, the WAF rules were tuned once, and since then the whole stack has been waiting for its first real event. Cloudflare’s 2026 Threat Report counted 47.1 million DDoS attacks mitigated in 2025, more than double the year before, so the first real event is a matter of when. A DDoS stress test is how you find out whether your defenses hold before an attacker does. It also happens to be a term with a split personality: the same words describe a legitimate, regulator-expected security exercise and a category of criminal service. This guide covers both meanings, because knowing where the line sits is the first thing a security team, a compliance officer, or an auditor will ask. The short version - A DDoS stress test sends real attack traffic against infrastructure you own, with your explicit authorization. Ownership is proven before any traffic flows. That authorization is what makes it a test rather than an attack. - Authorized testing is legal and increasingly expected. DORA requires EU financial entities to test ICT systems supporting critical functions regularly; FINMA expects Swiss institutions to demonstrate operational resilience, not assert it. - Booter and stresser services are the criminal version. Europol announced on 11 December 2024 that Operation PowerOFF had taken 27 such platforms offline across 15 countries. The operators were arrested, and more than 300 users were identified for follow-up. - It is not a load test. A load test measures capacity under friendly traffic. A stress test measures defenses under adversarial traffic, and the two fail in completely different places. - A proper run is scoped, DNS-verified, ramped gradually, abortable live, and ends in an attested report. If a provider skips any of those steps, walk away. ## What is a DDoS stress test? A DDoS stress test is a controlled simulation of a distributed denial-of-service attack, run against systems you own or operate, with documented authorization, to measure whether your defenses detect and absorb it. The traffic is real. The sources are distributed. The only difference from an actual attack is consent, control, and a report at the end. That definition carries three load-bearing words. Controlled means the traffic ramps up on a schedule you set and stops the moment you say stop. Authorized means the target has proven, in a verifiable way, that the infrastructure is theirs to test. Measure means the point is evidence: which controls fired, which stayed blind, at what traffic level the service degraded, and whether anyone on your side noticed. Remove any one of those three and you no longer have a stress test. Traffic without control is an outage you scheduled for yourself. Traffic without authorization is a crime, whoever launches it. And traffic without measurement teaches you nothing you can act on or show an auditor. ## Is a DDoS stress test legal? Testing infrastructure you own, with documented authorization, is legal. It is the same legal footing as penetration testing, and regulators have moved from tolerating it to expecting it. DORA, the EU’s Digital Operational Resilience Act, requires financial entities to test ICT systems supporting critical or important functions at least yearly under Article 24, and its list of test types explicitly includes scenario-based testing of the kind a DDoS simulation delivers. FINMA expects Swiss-regulated institutions to demonstrate operational resilience with evidence. NIS2 extends similar testing expectations across EU essential and important entities. Attacking infrastructure you do not own is a crime in essentially every jurisdiction, and the services that sell it get dismantled with some regularity. Booter and stresser sites, which offer to flood an arbitrary target for a few dollars, are the version of “DDoS stress testing” that ends in prosecution. Europol announced on 11 December 2024 that Operation PowerOFF, a multi-year international action against DDoS-for-hire services, had taken 27 of the most popular platforms offline across 15 countries, with three administrators arrested in France and Germany. The part many people miss: enforcement does not stop at the operators. In that same December 2024 action, more than 300 users of the seized platforms were identified for follow-up, Dutch prosecutors charged four people for attacks run through booters, and the US Department of Justice charged platform administrators. Several national police forces even bought search-engine ads against booter-related keywords, so a person searching for one of these services now finds a warning where the storefront used to be. The line the law draws runs through authorization and ownership, and nothing else. A bank commissioning a 200,000-request-per-second simulation against its own e-banking portal, with change-management sign-off and a signed scope, is doing what its regulator asked. An individual paying to send a fraction of that traffic at someone else’s server is committing an offense. Same packets, opposite legal categories. This is also why the authorization step in a legitimate test is not paperwork theatre. A provider that will send traffic anywhere a customer points it is a booter with an invoice. A provider that refuses to send a single packet until domain ownership is cryptographically proven has made the abuse case structurally impossible, which is exactly the property you want to show an auditor. ## How is a stress test different from a load test? Teams often assume their load testing covers this ground. It does not, and the gap is worth spelling out because it is where budgets go wrong. A load test answers a capacity question: how many well-behaved users can this system serve before response times degrade? The traffic is friendly by design. It follows the happy path, completes every request, reuses connections politely, and comes from a handful of cloud instances your firewall has probably been told to ignore. A DDoS stress test answers a defense question: what happens when the traffic is shaped to hurt? Attack traffic does things legitimate users never do. It holds connections open without finishing requests, busts caches with randomized queries, burns CPU with handshakes it never uses, or arrives as complete, valid requests from tens of thousands of sources at once. Each of those behaviors targets a different layer, and none of them shows up in a load test. The consequence is that the two tests fail in different places. A load test finds an undersized database pool or a slow endpoint. A stress test finds that your rate limiter keys on requests per second while the attack sends almost none, that your scrubbing provider needed twelve minutes to engage, or that your dashboards looked normal for the entire outage. Our post on the types of DDoS attacks walks through why each attack class defeats a different control, and the record for sheer scale keeps moving: the largest attack in Cloudflare’s 2026 Threat Report, a 31.4 terabit-per-second flood from the Aisuru botnet in late 2025, was nearly six times the biggest attack of 2024. One more difference matters for realism. Load generators run from a few datacenter IP ranges, which per-IP limits and reputation filters catch trivially. Real attacks come from botnets of tens of thousands of residential and mobile devices. A test that comes from three cloud instances validates your defenses against three cloud instances, and nothing else. This is the false-pass problem, and it is the single most common way a cheap check produces a dangerous conclusion. Our pillar guide on how to test your DDoS protection covers it in detail. ## How does an authorized DDoS stress test actually run? A legitimate test has a recognizable shape. If you are evaluating providers, or building an internal case for a first run, these are the steps that should exist. Where one is missing, that is a finding about the provider. ### Scoping before anything else You define which domains and services are in scope, which simulation types will run, what traffic levels the run will reach, the time window, and who on your side is watching. You also define the abort criteria in advance: at what point does the run stop even if nobody presses the button. Regulated institutions typically route this through change management, and that paper trail is what makes the exercise auditable later. ### Ownership verification, cryptographic rather than contractual Before any traffic flows, you prove the target is yours. On the Obsidio platform this is a DNS TXT record: you place a verification token in the DNS zone of the domain under test, which only someone with administrative control of that domain can do. No token, no traffic. A signature on a contract asserts ownership; a DNS record demonstrates it. This single step is what separates an authorization-first platform from a booter, because it makes pointing the traffic at a third party impossible rather than merely forbidden. ### Gradual ramp, live metrics, instant abort A proper run does not open at full scale. It starts in a controlled window with conservative limits and ramps up as confidence grows, while you watch real-time metrics: requests per second, success rate, data transferred, and how your edge responds. Any run can be aborted live, at any second. That combination, ramp plus abort, is what turns a simulated attack into a controlled experiment. You find the level at which degradation begins without being forced to ride through it. ### A report you can hand to an auditor The run ends with evidence, not a screenshot. Obsidio generates cryptographically attested, tamper-evident reports inside Trusted Execution Environments, mapped to FINMA, DORA, and NIS2 expectations. The distinction matters more than it first appears: an attested report is an artifact a third party can verify, while an internal test log is a claim your own team has to vouch for. Auditors know the difference. ## What should a stress test actually cover? One test type is not coverage. Attacks fail in genuinely different places, and a defense tuned for one class can be structurally blind to another. A volumetric flood exercises your bandwidth and scrubbing; a slow attack like Slowloris sends almost no traffic at all and walks past every rate-based control; a TLS flood burns CPU on handshakes; a flood of real browser sessions defeats bot detection because there is no bot to detect. Obsidio runs ten simulation types across four categories: application-layer floods, slow attacks, connection exhaustion, and protocol-specific or scripted traffic. A sensible first programme does not run all ten at once. It starts with the classes most relevant to your architecture, then expands. The attack-type overview explains which class stresses which layer, and the product page lists the full catalog. Coverage also has a second axis that teams forget: detection. Every run should answer not only “did the defenses hold?” but “did anyone find out?” Whether your dashboards moved, whether your SIEM logged anything, and whether on-call was paged are answers that live on your own consoles, so someone on your side needs to be watching during the window. A control that fails silently and a control that works invisibly are both findings. ## How often should you stress test? A single test is a snapshot, and infrastructure does not stand still. The CDN contract gets renegotiated, an engineer relaxes a timeout to fix a customer complaint, a new API ships outside the WAF policy. Any of those can quietly undo a result that was true six months ago. For regulated financial entities the floor is set externally: DORA expects ICT systems supporting critical or important functions to be tested at least yearly, and our guide to DORA compliance covers what evidence that testing has to produce. Treat that as a minimum rather than a target. Beyond the regulatory floor, two triggers matter more than the calendar. Retest after you fix something, because a mitigation that was configured under pressure and never exercised is exactly the kind of control that fails twice. And retest after material changes to the edge: a new CDN, a migration, a new public-facing service. The cadence the platform is built around is a loop, “Configure. Test. Adapt. Retest.”, precisely because the second run is where you learn whether the first one changed anything. ## What does a stress test find that a config review cannot? Configuration reviews verify that settings exist. They cannot verify that settings hold under concurrency, that vendor claims survive contact with realistic traffic, or that the interaction between your CDN, your load balancer, and your origin behaves the way the diagram says. Those properties only exist under real traffic. The typical findings from a first authorized test are rarely “the protection is missing.” They are quieter and more expensive than that. The scrubbing service engaged, but minutes after degradation began. The rate limiter worked, and also throttled the payment callback from a partner. Failover worked, and the failover environment had a quarter of production capacity. Auto-scaling scaled, and the invoice arrived. None of those appears in a config review, and every one of them changes what you do next. Strength is proven, not promised. Buying DDoS protection settles what you spent. A stress test settles what you can survive. There is also the organizational finding. An attack at 3 a.m. is a people event as much as a technical one, and the first authorized run is usually the first time the escalation path gets exercised end to end. Finding out that the runbook names a person who left last year is cheap during a scheduled window. It is very expensive during a real attack. ## Where to start Start small and legitimate. Pick one service, get sign-off, verify ownership, and run one attack class at conservative scale during a window your team is watching. The first run is less about the traffic level than about proving the loop works: authorize, configure, simulate, report. Every later run gets faster and more ambitious. Obsidio runs DDoS stress tests as controlled, authorized simulations from 100,000+ globally distributed real devices, so per-IP limits and reputation filters get tested the way an actual distributed attack would test them. Domain ownership is verified by DNS TXT record before a single request is sent, runs ramp up gradually, any run can be aborted live, and the result is a cryptographically attested report mapped to FINMA, DORA, and NIS2. To scope an authorized stress test against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # What Is a Botnet? How Hijacked Devices Power DDoS Attacks URL: https://obsidio.com/what-is-a-botnet/ Published: 2026-07-29 In November 2025, Cloudflare absorbed the largest DDoS attack ever publicly disclosed: 31.4 terabits per second, sustained for 35 seconds. The traffic did not come from a data center. It came from a botnet, an estimated one to four million hijacked consumer devices, most of them cheap Android TV boxes whose owners had no idea they were participating. That is the defining property of a botnet, and the reason it is the delivery mechanism behind almost every large DDoS attack: the attacker never owns the hardware. You do. Or your customers do. The short version - A botnet is a network of hijacked devices (routers, cameras, TV boxes, servers), infected with malware and remotely controlled by an operator without the owners’ knowledge. - Recruitment is industrial. Malware like Mirai scans the internet for devices with factory-default passwords or unpatched flaws and enrols them in minutes. Mirai reached roughly 600,000 devices at its 2016 peak. - DDoS is the flagship use. A botnet aims the combined bandwidth of its members at one target. The November 2025 record of 31.4 Tbps came from the AISURU botnet’s hijacked Android TVs. - Botnet traffic is hard to filter because it arrives from millions of real residential devices with legitimate IP addresses, not from a few conspicuous servers. - You can test against it without touching one. Obsidio reproduces botnet-scale traffic with 100,000+ real, ethically sourced devices: authorized, controlled, abortable at any moment. ## What is a botnet? A botnet is a network of internet-connected devices that have been infected with malware and placed under the remote control of a single operator, the “bot herder”. Each infected device is a “bot” (or “zombie”). The owners almost never know: the device keeps working, and the malware runs quietly in the background. Three components make the system work: - The bots. Any device with a processor and a network connection qualifies: home routers, IP cameras, video recorders, smart TVs, set-top boxes, cloud servers, occasionally desktop PCs. The 2016 Mirai botnet was built almost entirely from consumer IoT devices; the 2025 AISURU botnet from off-brand Android TV boxes. - The command-and-control channel (C2). The infrastructure through which the operator issues orders: classically a central server, in newer designs a peer-to-peer mesh with no single point to take down. - The operator. Increasingly not the person using the botnet. Large botnets are rented out as “DDoS-for-hire”, so the person aiming the traffic at a bank may have paid a subscription fee measured in tens of dollars. ## How does a device become a bot? Not through anything the owner did. Botnet malware finds devices on its own, by scanning the entire internet for three kinds of weakness: - Factory-default credentials. Mirai’s method, and still the most productive one. The malware carries a short list of default username/password pairs (admin/admin, root/12345) and tries them against every device it finds. According to the USENIX Security 2017 analysis of Mirai, that alone grew the botnet to a peak of roughly 600,000 infected devices. - Unpatched vulnerabilities. Consumer devices rarely receive updates. A flaw disclosed in a router firmware in one year is still exploitable on millions of units years later. - Trojanized software and supply chains. The AISURU botnet was built largely from compromised, off-brand Android TV boxes: devices that were subverted at or near the point of sale rather than broken into afterwards. Every new bot immediately starts scanning for further victims, which is why botnet growth is exponential. Mirai infected nearly 65,000 devices in its first 20 hours, doubling in size roughly every 76 minutes early on. ## What are botnets used for? The combined resources of a million devices are the product: bandwidth, IP addresses, compute. The operator sells or uses them for: - DDoS attacks. The flagship use case, and the one this blog cares about. All members flood one target simultaneously; the target’s capacity is exhausted; legitimate users are locked out. - Credential stuffing. Trying leaked username/password pairs against login pages, distributed across thousands of IPs so rate limits never trigger. - Spam and phishing delivery. Residential IPs pass reputation filters that data-center IPs fail. - Residential proxy networks. Renting the bots’ IP addresses to whoever wants their traffic to look like it comes from a household. - Cryptomining. Stealing electricity and compute at scale. ## Why is botnet traffic so hard to filter? Because each request, taken alone, looks legitimate. This is the property that breaks naive DDoS defenses: - Real devices, real IPs. The traffic originates from genuine consumer hardware on residential connections, the same address space as your customers. Blocking by IP reputation blocks customers too. - Distribution. A million sources sending one request each defeats per-IP rate limiting entirely. No single source ever crosses a threshold. - Real browsers, real behavior. Modern botnets on Android hardware can run genuine browser engines, execute JavaScript, and pass bot-detection challenges. Our Browser Flood post examines that scenario in detail. - Geographic spread. Traffic arrives from every region at once. Geo-blocking cuts off markets, not the attack. The uncomfortable conclusion for defenders: a filter tuned to catch “obviously fake” traffic will pass most of what a modern botnet sends. ## From Mirai to AISURU: how big do botnets get? Three data points, each a public record in its day, show the trajectory: - September 2016: Mirai vs. KrebsOnSecurity. Over 600 Gbps against a single journalist’s website, from roughly 600,000 infected IoT devices (Antonakakis et al., USENIX Security 2017). - October 21, 2016: Mirai vs. Dyn. The same botnet aimed at a DNS provider took Twitter, Netflix, Spotify and Amazon offline for large parts of the US and Europe. One company’s resolvers were attacked; half the internet felt it. - November 2025: AISURU vs. Cloudflare customers. 31.4 Tbps, roughly fifty times the Krebs attack, from an estimated one to four million devices, followed by an HTTP campaign exceeding 200 million requests per second (Cloudflare DDoS threat report, Q3 2025). And the pace is accelerating. The public record fell four times in the thirteen months to November 2025 alone: The growth is driven by supply: every year adds billions of cheap, unpatched, internet-connected devices, and every one of them is a potential bot. ## What do botnets mean for regulated institutions? For a bank, insurer or financial market infrastructure, the botnet threat translates into a concrete regulatory expectation: prove that your services stay available under exactly this kind of load. - DORA (Regulation (EU) 2022/2554) requires digital operational resilience testing of ICT systems supporting critical functions at least yearly (Article 24), with scenario-based testing among the listed methods (Article 25). - FINMA expects Swiss institutions to manage operational risks to critical services, including cyber scenarios, under Circular 2023/1. - NIS2 (Directive (EU) 2022/2555) obliges essential and important entities to take measures ensuring service continuity, including attack resilience (Article 21). None of these frameworks accepts “we have a DDoS protection contract” as evidence. They ask whether the defense works. The only way to know is to subject it to realistic pressure. ## How do you test against botnet-scale traffic, without a botnet? This is the problem Obsidio was built to solve. A realistic test has to reproduce the properties that make botnet traffic dangerous (real devices, residential networks, global distribution, genuine browser behavior) without ever touching a hijacked machine. Obsidio runs DDoS simulations from 100,000+ real, ethically sourced devices distributed worldwide: hardware whose owners deliberately contribute capacity, orchestrated inside Trusted Execution Environments with full audit logging. The traffic is indistinguishable from a genuine botnet attack, because it has the same shape. But every simulation requires explicit ownership verification of the target, runs under your control with progressive ramp-up, and can be aborted instantly from live metrics. In other words: the realism of a botnet, with the authorization, control and evidence a compliance team needs. Every run produces a cryptographically attested report that maps to FINMA, DORA and NIS2 expectations. If you want to know how your defenses behave when a million polite-looking requests arrive at once, start with our guide on how to test your DDoS protection, or talk to our team about a controlled simulation against your own infrastructure. ======================================== # Puppeteer Script Testing: How It Works and What It Measures URL: https://obsidio.com/puppeteer-script-testing/ Published: 2026-07-22 The other nine simulation types in this series answer one question: does your edge hold when hostile traffic arrives. Worth knowing, and not the only question. There is a second one no flood can settle. Does your login still work when a thousand people sign in at once, and does the session store cope. Puppeteer Script is the entry in Obsidio’s catalogue built for that question. It is not a flood and not measured in requests per second. It takes a script you wrote, runs it against a real browser page on every worker at once, and reports whether each run finished. Synthetic user testing under genuine concurrency, reaching parts of a banking stack raw traffic never gets near. The short version - This one is functional load, not an attack. The platform files it under browser automation. No fixed traffic pattern, because the workload is whatever your script does: a login, a form submission, a full journey. - You supply the script. JavaScript runs against a real Chromium page object, one browser per worker, looping until the duration expires. Concurrency comes from the number of workers, nothing else. - The metric is iterations, not request rate. Each loop is one attempt with its own timeout. You read per-iteration success and wall-time, and no requests-per-second estimate is shown for this type at all. - It reaches the database. This and Browser Flood are the only two of the ten that run your real pages, so they are the only two that exercise the application tier, the authentication path and the session store. - Writing the script is not the hard part. Your QA team can already do that. The gap is running it from thousands of real devices in many countries at once. This is one entry in a series covering each of the ten simulation types Obsidio runs, one post per type. Nine are adversarial. This one is not, which is why it belongs in the set: it covers what the other nine leave unmeasured. For how the categories fit together, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. The last entry is functional load testing rather than an attack. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptyou are here ## What Puppeteer Script testing actually does Each worker starts a single Chromium tab and attaches Puppeteer to it. Puppeteer’s documentation describes it plainly: connect() “attaches Puppeteer to an existing browser instance”. The worker gets back a page object, which the docs define as providing “methods to interact with a single tab or extension background page in the browser”. Navigation, clicking, typing, evaluating JavaScript in the page context: all available, because this is a real browser, not a request generator wearing a browser’s user agent. Your script runs as the body of an async function, once per iteration, in a loop, until the run duration expires. Every iteration is a separate attempt with its own timeout, and an overrunning iteration gets killed and recorded as a failure with the reason attached. A syntax error throws once at startup and fails the whole run. There is no traffic pattern to describe here, which is what separates this from every other type in the catalogue. A flood has a shape; this has whatever shape your journey has. A payment initiation might be a dozen calls, two of them to systems you do not own. The plain version: you write a small browser bot that does one job, log in, fill a form, click a button, and the platform clones it onto every worker and runs it on repeat for the duration of the simulation. ## What synthetic user testing is good for Floods answer questions about capacity and filtering. Scripted journeys answer questions about correctness under load, a separate property that fails separately. Grafana’s k6 project, which offers browser-level load testing alongside the protocol-level kind, puts the same point plainly: browser-level testing “provides a way to measure user experience and find issues that are difficult to catch on the protocol level”. Four things are worth testing this way. Business flow verification under concurrency. The question is not whether the page returned a response but whether the transfer was created and the confirmation showed the right amount. Assertions inside the script record that per iteration, so the result is a pass rate on the flow, not a latency chart. Authentication and session behaviour. Login is where banks accumulate the most fragile machinery: token issuance, session storage, step-up verification, limits meant to stop credential stuffing. Under a thousand concurrent sign-ins those interact in ways nobody designed, and a protocol-level test replaying a captured token exercises none of it. The parts of the stack a flood never touches. A slow attack such as Slowloris stops at the web server and never reaches your application. A scripted journey writes to your database, occupies your session store, and calls whatever downstream service the flow depends on. Your own protective controls, seen from the customer’s side. If bot detection challenges the journey, or your WAF starts blocking a form submission at volume, you have learned how your controls treat genuine automated traffic, which every bank carries in its partner integrations. ## Which parts of your stack does this exercise For the attack simulations, the useful question is which control should have caught it. Here it inverts. Nothing is trying to get past anything, so the question becomes coverage: which layers this test genuinely reaches, and which it leaves alone. Zone 1 What sits in front, and why it barely matters - DDoS protection and scrubbing. Not in play. The traffic volume is ordinary and the test is not trying to look hostile. - Firewall and WAF. Sees complete, well-formed requests from your own journey. If it starts blocking form submissions at volume, that is a finding about your customers, not an intruder. - Rate limiting. Relevant only if your journey trips a per-account or per-endpoint limit, which some login flows do. - Bot detection and challenges. A real browser under automation is the ambiguous case. Only a run against your own configuration shows whether it gets challenged. - CDN cache. Absorbs the static parts of the page, quietly reducing how much of the journey reaches your origin. Zone 2 What the test actually reaches - Load balancer or reverse proxy. Carries the traffic without being under pressure. - Web server. Serves the pages and their sub-resources at moderate volume. - Application tier. The target. Authentication, form handling, business logic, whatever your flow calls downstream. - Database and session store. Genuinely exercised, writes included. This and Browser Flood are the only two of the ten that get here, because they run your real pages and journeys. - Auto-scaling. Scales on whatever metric you configured. Whether your journey moves one of those metrics is a per-stack answer. Zone 3 Would you find out what broke? - Dashboards. Request rate stays unremarkable throughout. Whether failed logins or slowing transfers show up depends on what you chose to graph. - Per-iteration results. What carries this test: iteration success rate and iteration duration, not throughput. - Logging and your SIEM. The journey produces ordinary log lines at unusual volume. Check whether anything correlates them into a signal. - Infrastructure alerting. Usually silent. A flow returning the wrong answer crosses no CPU or bandwidth threshold. - Fraud and security monitoring. Hundreds of simultaneous sign-ins from many countries should register somewhere. If nothing does, that is a finding of its own. Purple marks what only a run on your own infrastructure can settle. Everything else follows from how the test works. ## The parameters, and how this differs from Browser Flood Four things are configurable, and one does most of the work. - The script. The main lever. It receives the page object, a context object carrying the target URL and your parameters, and helpers for delays, logging, named assertions and custom metrics. A slower script means fewer iterations per worker in the same duration. - Iteration delay. The pause between iterations, one second by default, adjustable from 100 milliseconds to 10 seconds. It also sets the per-iteration timeout: five times the delay, or 30 seconds, whichever is larger. Raising it slows the loop and gives each iteration more headroom before it is killed. - User agent. Pinned for the run if you set it, otherwise whatever the browser runtime ships with. - Headers. Extra HTTP headers applied to every request the page makes. Puppeteer documents these as sent “with every request the page initiates”, which is what makes them usable for an auth token or a test-only bypass header. Two constraints matter. One browser per worker, with no parallelism inside a worker: iterations run back to back, so concurrency is the worker count alone. And it requires the browser runtime on the worker device, with no HTTP fallback. Without the runtime it throws immediately instead of quietly degrading into something less realistic, which is what you want from a test whose whole value is the real browser. Browser Flood is the sibling that confuses people, since both drive real Chromium. The difference is what they load. Browser Flood loads your page repeatedly and counts every sub-resource the engine fetches, so the load takes the shape of the HTML, CSS, JavaScript, images and background calls your page pulls. Puppeteer Script ignores the sub-resource graph and follows the journey instead: navigate, type, submit, check the result. One produces realistic volume, the other realistic behaviour. ## What you can check yourself, and where the gap is The honest answer here differs from the other nine posts. Your team can script these journeys. If you already do web application load testing with the mainstream tools, or keep end-to-end browser suites in your pipeline, you have the skill and most of the code. The gap sits in two other places. Concurrency at a realistic scale. Every browser session costs real memory and CPU on the machine driving it. The k6 documentation is direct about the consequence, noting “an additional performance overhead when it comes to spinning up a browser VU” and offering as a less resource-intensive alternative “combining a small number of virtual users for a browser test with a large number of virtual users for a protocol-level test”. That compromise is sensible advice for a CI budget. It also leaves your original question unanswered: what your session store does at a thousand concurrent real journeys. Geographic and network distribution. A hundred browser sessions from one cloud region share a handful of addresses, one network path and one latency profile. A busy Monday morning looks nothing like that, and that setup cannot tell you how your geo-based rules, bot scoring or fraud monitoring behave when the same flow arrives from thirty countries at once. So run your own scripted journeys against staging. Just do not read a clean result at low concurrency from one location as evidence the flow holds at scale. ## How to run this against production safely Authorization comes first, and it is not a checkbox. Obsidio verifies domain ownership through a DNS TXT record before any traffic flows, runs ramp up gradually rather than starting at full worker count, and any run can be aborted live. A scripted journey adds one piece of homework: your script creates real records, so decide in advance which account it uses, what it writes and who clears up afterwards. A journey submitting a thousand transfer requests needs the same change-management sign-off as any other production activity. Where the workers come from is what closes the gap above. Obsidio runs simulations across 100,000+ globally distributed real devices, so a scripted journey arrives from many countries and networks at once rather than from one rented region. Then watch the right numbers, because two habits carry over badly from flood testing. - Ignore request rate. No throughput estimate is shown for this type, deliberately. Read iteration success rate and iteration duration instead. Duration here is the wall-clock time of the whole journey, not the time to first byte of one request, so it compares with what a customer experiences. - Assert, do not assume. A page that loads is not a flow that worked. Put named assertions in the script for whatever must be true, the confirmation text, the balance, the redirect target, and read the pass and fail counts. Custom values you report per iteration come back with the results, so extract the reference number proving the transaction happened. The reporting split is the same as everywhere else. Obsidio measures what is visible from outside: whether each iteration completed, how long it took, which assertions passed, how your edge controls responded. Whether your database connection pool saturated, whether your SIEM correlated anything and whether anyone was paged are answers only your consoles hold. Have someone watching during the window, or the run produces half a finding. Strength is proven, not promised. A flood asks whether your defences hold. A scripted journey asks whether your bank still works while they do. ## Where this fits in a testing programme A programme built only from attack simulations has a large blind spot. Each of the other nine types tells you something about capacity, filtering or connection handling. None tells you whether the transfer completed. For a regulated institution, resilience means customers could still do what they came for, and verifying that needs a test that does the thing. The pairing that makes it concrete: run a flood against the front of the stack and a scripted journey alongside it, then see whether the journey still completes while the flood lands. That is as close as a controlled simulation gets to the question a board asks after an incident, and it is the pairing the k6 documentation recommends too, a small browser workload next to a large protocol-level one rather than a choice between them. For regulated institutions the record matters as much as the result. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so an authorized functional load run leaves an artifact you can file rather than a screenshot somebody has to vouch for. To scope an authorized synthetic user test against your own infrastructure, see the Obsidio platform or get in touch. Independent, neutral, verifiable: resilience you can prove. ======================================== # TCP Connection Flood: How It Works and How to Test Your Defenses URL: https://obsidio.com/tcp-connection-flood/ Published: 2026-07-10 A TCP connection flood never sends any data. It opens connections, completes the handshake, then says nothing for as long as the socket is allowed to live. There is no request to inspect, no payload to filter and no signature to match, because nothing above the transport layer ever happens. That makes it awkward to defend against and easy to miss. Bandwidth stays flat and requests per second stay flat. What fills up is a set of counters most teams have never put on a dashboard: connection-table entries, file descriptors, connection-tracking slots and the queue of connections waiting to be accepted. The service stops answering while every graph anyone is watching reads normal. The short version - Nothing is ever sent. No HTTP, no TLS, no payload, no negotiation beyond the handshake. An idle socket produces no traffic, so there is nothing to inspect and nothing for a volume-based defense to trigger on. - It exhausts counters, not capacity. Connection-table entries, file descriptors, connection-tracking slots, per-source socket limits and the accept queue. None appear on a bandwidth or request-rate graph. - A WAF is not a firewall, and here that difference decides the outcome. A WAF inspects HTTP and cannot see this traffic at all. A network firewall works at the layer that can. - It is the cheapest attack per socket we run. No crypto cost on either side, unlike a TLS flood. - A single-source test will tell you that you are fine. A per-IP connection cap stops one machine in seconds and does little against a distributed flood, so the cheap check passes where the real risk lives. This is one post in a series covering each of the ten simulation types Obsidio runs. They fail in genuinely different places, which is why a test programme needs coverage across the categories rather than volume in one of them. For how they fit together, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Floodyou are here Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a TCP connection flood actually does Each parallel slot opens one raw TCP connection, lets the handshake complete, and holds the socket idle until a configured timeout expires. Then it closes and opens a fresh one. There is no HTTP layer and no TLS layer above it, and no application data is written in either direction. A TCP flood attack of this kind is about occupancy rather than packet volume, and the connections it holds are fully established rather than half-open. What that consumes is a set of finite slots. Every established connection occupies an entry in the server’s connection table, an open file descriptor in the process holding it, a connection-tracking entry in every stateful device on the path, and a share of whatever per-source socket limit applies. Connections arriving while the accept queue is backed up wait in it, and once it is full they are refused. None of those are CPU or bandwidth, which is why the attack is so quiet. Twenty people each phone the shop and say nothing. Every line is occupied, the staff are sitting there ready to help, and real customers get a busy signal. A socket that has connected and not yet spoken is not suspicious on its own. A mobile client on a bad connection looks the same. That is why servers do not simply hang up, and why the defense has to be a limit rather than a rule. ## Which of your controls should have caught this It is worth walking the whole chain a connection passes through, because the answer here is narrower than most teams expect. What sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - Web application firewall. Inspects HTTP requests. No request is ever made, so it has nothing to evaluate. - Network firewall. The one control at the right layer. Whether it caps connections per source, and whether its own tracking table has headroom, is a question about your configuration. - Volumetric DDoS protection. Watches bandwidth and packet rate. An idle socket generates neither. - Rate limiting and bot detection. One counts requests, the other profiles client behaviour. There is neither. - A proxy or scrubbing layer that terminates TCP for you. Real protection where it exists, provided your origin cannot be reached directly. Zone 2 What takes the hit? - Load balancer or reverse proxy. If it terminates connections, its own limits decide the outcome. Confirm which component holds the socket. - Connection tracking and the accept queue. One entry per socket, and new arrivals queue behind everything already held. - The listening service. Where it bites. The per-worker connection ceiling and the open-file limit are hard walls, and the lower one is what you hit. - Application and database. Never reached. No request is made, so no handler runs and no query is issued. - Auto-scaling. CPU, bandwidth and request rate all look idle, so nothing scales. More nodes would not help a shared stateful device anyway. Zone 3 Would you find out? - Bandwidth and request-rate dashboards. Flat throughout. Both are measuring the wrong thing. - A concurrent-connections or tracking-table graph. The one internal metric that shows this clearly. Whether it exists, and whether anyone watches it, is a real question. - A check from outside your network. Catches it reliably, because new connections stop being accepted. Only useful if you run one. - Access logs and your SIEM. No request means no access-log line. Anything recorded lands in an error log, under a resource-limit message rather than an attack. - Alerting and on-call. Nothing crosses a threshold. The service is refusing connections and the room is quiet. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. The firewall and the WAF are worth separating properly, because this is the attack where treating them as one box gets people badly wrong. A web application firewall reads HTTP: request lines, headers, query strings, bodies. A connection that completes the handshake and then stays silent gives it none of that, and a client which has not spoken yet is not an anomaly a rule can be written against. The WAF is not misconfigured. The traffic is below the layer it works at. A network firewall works with addresses, ports and connection state, which is what this attack manipulates, so it can count how many established connections one source holds and refuse the next. In netfilter that is the connlimit match, where --connlimit-above sets the threshold and --connlimit-mask groups sources by prefix length; nftables has ct count. It pays for being in the game, though: every connection it tracks costs an entry in its own table, so the control best placed to see the attack is also a resource the attack consumes. ## The parameters, and what this is not Four settings, each mapping to a resource on your side: - Sockets held per worker. Default 20, range 1 to 100. Multiplied by the worker count, this is how many entries you are asking the target’s connection table to hold. The real ceiling is the smaller of that product and the target’s per-source and global socket limits. - Idle timeout. Default 600,000 milliseconds, or ten minutes, settable from 100 milliseconds to an hour and capped at the run duration. Higher holds sockets longer, so pressure is sustained and the open rate falls. Lower churns faster, shifting load to accept and teardown work instead of occupancy. - Think time. Default 0. How long a slot waits after a socket closes before opening the next, which paces the replacement rate. - Port. Defaults to 443 or 80 from the target URL scheme. The scheme only picks the number; the connection is plain TCP either way. A TLS flood also abandons connections, but it makes the server complete a full handshake first, including key exchange, certificate and session setup, and that asymmetric crypto costs the server roughly fifteen times what it costs the client. The target is CPU. A TCP connection flood spends nothing on crypto at either end, and its cost to the target is one table entry and one descriptor. Slowloris is different again. It speaks HTTP, sending a partial request and then trickling, which is why header-read timeouts and a buffering proxy defeat it. A TCP connection flood sends no HTTP at all, so anything reasoning about request content is out of scope here, not merely weak. ## How to defend against a TCP connection flood Everything useful here is a number, and every number can be stale, wrong, or lower than you assume. These are the ones to check, with documented defaults where they exist: - Per-source concurrent connection limits, at the network layer. netfilter’s connlimit match with --connlimit-above is the direct tool, and --connlimit-mask groups a source network rather than one address. One warning: nginx’s limit_conn does not cover this case. Its documentation is explicit that “a connection is counted only if it has a request being processed by the server and the whole request header has already been read”. A socket that never sends a request is never counted. - Connection-tracking capacity. In the Linux connection tracker, nf_conntrack_max defaults to four times the bucket count, and on a machine with more than 4 GB of memory the bucket count defaults to 65,536. More importantly, nf_conntrack_tcp_timeout_established defaults to 432,000 seconds, which is five days. An idle established connection keeps its entry for days unless something else closes the socket. - File-descriptor limits. Every socket is an open file. fs.file-max caps the handles the kernel will allocate system-wide, with no documented default because it is sized per system. Per-process limits usually bind first: nginx sets worker_connections to 512 per worker, counts proxied connections as well as client ones, and notes the count “cannot exceed the current limit on the maximum number of open files”, raised with worker_rlimit_nofile, which has no default. Trust the smaller number. - Accept-queue depth. nginx sets the listen backlog to 511 on Linux by default, and whatever a service asks for is silently capped to net.core.somaxconn, which defaults to 4096 since Linux 5.4 and to 128 on earlier kernels. A short queue turns held connections into refused ones sooner. - Idle timeouts, at a layer that has one. The transport layer will not help by default: tcp_keepalive_time defaults to two hours, then nine probes at 75-second intervals. nginx does better, with client_header_timeout at 60 seconds for reading a request header and keepalive_timeout at 75. Whether every listener in your stack has an equivalent is the thing to verify, and plenty do not. A listener with a 60-second header timeout will close these sockets, since the simulation holds them for ten minutes by default. That moves the interesting question rather than answering it. What happens in front of the listener, in the firewall’s table, the load balancer and the accept queue, is where the run gets decided. ## What you can check yourself, and what it will get wrong Two of these you can do this afternoon. The third is the one that misleads. Read the numbers and do the arithmetic. Pull the connection-tracking maximum, the descriptor limits, the per-worker connection ceiling, the listen backlog and somaxconn. The smallest is your real capacity. This is free, takes an hour, and often surprises people. It tells you where the ceiling is, not what happens when you reach it. Test alert routing on its own. Fire a synthetic alert and see whether it reaches the right rotation and whether anybody acts on it. That needs no attack traffic. Open a lot of connections from one machine against staging infrastructure you own, with change-management sign-off. Legitimate, and this is where the trap is. The arithmetic is worth spelling out. Say your per-source cap is 100 concurrent connections. One machine tries to open five thousand and is stopped at 100. Refusals appear in the firewall counters, the connection count barely moves, the service stays healthy, and the test is written up as a pass. The result is accurate. The conclusion drawn from it is wrong, because the control that just proved itself is close to the least relevant one for the scenario you are afraid of. Now distribute it. Ten thousand sources each hold twenty connections. Every source sits far below the cap, so not one breaks a rule, and your table is carrying two hundred thousand established connections. Same firewall, same configuration, opposite outcome. A per-source cap does not reduce the total capacity that can be consumed; it limits any one source’s share. Against enough sources the binding constraint moves to your tracking table and descriptor ceiling, the numbers the single-source test never came close to because the cap stopped it at 100 first. Prefix masking has the same problem: grouping by network catches a rented block at one hosting provider and does little against residential addresses spread across thousands of unrelated networks. Once the cap looks like the defense, nobody raises the underlying limits and nobody graphs the tracking table, so the finding that mattered is never generated. And no configuration review tells you how the stack behaves at its ceiling. Some services refuse new connections cleanly, some stall, some fail their health check and get pulled from rotation while still running. ## How Obsidio tests a TCP connection flood Obsidio runs this as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually rather than starting at full load, and any run can be aborted live. You choose the sockets per worker, the idle timeout, the think time and the port. Load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances. That is the part a self-test cannot reproduce: a per-source cap gets exercised the way a distributed flood would exercise it, across many networks, each source individually unremarkable. - Ignore the request-rate figure. The displayed rate counts socket opens, not throughput, and the per-slot estimate is one. It looks trivially low while the run is succeeding. Watch concurrent connections and the peak instead, plus the open-attempt rate if you are testing churn rather than occupancy. - Measure reachability from outside. What users experience is a connection that is not accepted, and server-side metrics can hide that. Be clear about the split before you start. Obsidio measures how many connections were held, the peak, the open rate and whether the service stayed reachable from outside, because that is visible externally. Whether your descriptor ceiling or tracking table actually saturated, what your error log recorded and whether anyone was paged live only on your own consoles. Have someone watching them during the window. Strength is proven, not promised. A TCP connection flood does not test your bandwidth or your rules. It tests whether the limits your stack was sized with are still the limits it is running. ## Where this fits in a testing programme TCP Connection Flood belongs in the connection-exhaustion category alongside TLS Flood. Both aim at the connection rather than the request: one buys CPU time with the server’s own cryptography, the other buys table space with silence. A stack that absorbs one can fail the other, which is why the category needs both. Across the ten simulation types the failure point moves considerably. An application-layer flood gives your front defenses something to act on, reaches as far as your database connection pool, and turns the detection problem from silence into noise. This one stops at the transport layer, is invisible to your WAF, and is decided by five or six integers in configuration files. For regulated institutions the run also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the outcome is an artifact you can file rather than a screenshot you vouch for. To scope an authorized TCP connection flood simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # TLS Flood: How It Works and How to Test Your Defenses URL: https://obsidio.com/tls-flood-attack/ Published: 2026-07-06 A TLS flood never asks your server for anything. It opens a connection, lets the server complete the full cryptographic handshake, then destroys the socket. No request line, no Host header, no path. Nothing your web application firewall can read, because a firewall that inspects requests needs a request to exist. That is what makes this one awkward. The traffic is well-formed. Every connection is a legitimate TLS negotiation your server chose to complete. The cost is real and it lands on your side, because the arithmetic of public-key cryptography is not symmetrical. The client spends very little to ask. The server spends a great deal to answer. The short version - The server pays and the client barely does. Obsidio’s own measurements put the server-side CPU cost of a completed handshake at roughly fifteen times the client’s. That asymmetry is the whole attack. - There is no HTTP layer. The handshake finishes and the connection is abandoned before a byte of application data moves either way. - A WAF sees literally nothing. It operates on requests, at a layer this traffic never reaches, so tuning it differently would not help. - Where you terminate TLS decides the outcome. Handshakes landing on a CDN or load balancer built to absorb them never reach your origin. Landing on your origin, they land on your CPU. - Session resumption is not the fix people assume. It needs a key from a previous handshake, and a fresh connection has nothing to resume. This is one of a series covering each of the ten simulation types Obsidio runs, one post per attack. They fail in genuinely different places, which is why a test programme needs coverage across the categories rather than volume in one. For how they fit together, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Floodyou are here - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a TLS flood actually does The client opens a TLS connection and lets the server run the negotiation to the end: key exchange, certificate, session setup. The moment the secure connection is established, a very short idle timeout expires and the socket is destroyed. Then the slot opens another. The server has done the expensive part and learned nothing about what the client wanted, because the client never said. The expense is worth naming precisely. In a TLS 1.3 full handshake the server sends its key share, its certificate, and a CertificateVerify message that RFC 8446 describes as “a signature over the entire handshake using the private key”. TLS 1.3 also removed the static RSA and static Diffie-Hellman cipher suites, so every full handshake now includes an ephemeral key exchange. Private-key signing plus ephemeral key agreement, once per connection, before the server has any idea whether the connection is worth serving. The client’s half is cheap. It does its side of the key exchange, signs nothing, and throws the session away microseconds later without validating the certificate. Obsidio’s own measurements put the server’s CPU cost at around fifteen times the client’s. That figure is our instrumentation, not a published standard, and the multiple moves with your key type, cipher selection and whether offload hardware sits in the path. The direction never moves. Twenty people walk up to a high-security door. The guard runs the full identity check on each one, every document, every signature. Each then turns around and leaves. The guard burns out on visitors who never enter, and there is no visitor record afterwards because nobody was admitted. The naming is historical. Obsidio’s internal identifier is ssl-flood and the attack is still widely discussed as an SSL flood, but the implementation uses modern TLS with Server Name Indication set to the target host. ## Which of your controls should have caught this It is worth walking the whole chain a connection passes through, because the answer is rarely the control people expect. Three groups matter: what sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. Bandwidth stays low, so a volume threshold is the wrong trigger. Ask your provider whether it watches handshake rate per source. - Firewall and WAF. A WAF sees literally nothing. AWS describes its own as monitoring “the HTTP and HTTPS requests that are forwarded to your protected web application resources”. No request is ever forwarded. - Rate limiting. Usually keyed on requests. nginx documents that a connection is counted “only if it has a request being processed by the server and the whole request header has already been read”. - Bot detection and challenges. A challenge is delivered in an HTTP response. Nothing gets that far. - CDN. Potentially decisive, for one reason: it terminates TLS. Caching is irrelevant. Whether your origin still answers on its own IP settles it. Zone 2 What takes the hit? - Load balancer or reverse proxy. Absorbs the whole attack if it terminates TLS itself. Worth confirming yours does and that nothing bypasses it. - Connection layer. Churns rather than fills. Sockets appear and vanish, so the table never looks alarming. - TLS stack and CPU. This is where it bites. Asymmetric crypto per handshake, at whatever rate the fleet can sustain. - Application and database. Never reached, because no request is ever routed to them. - Auto-scaling. Depends on your scaling metric. Scale on CPU and it may respond. Scale on request rate and it never wakes. Zone 3 Would you find out? - Dashboards. The request-rate graph reads flat. The CPU graph on your TLS terminators does not. Whether anyone watches the second is the finding. - Access logs and your SIEM. Access logs are written per request. There are no requests, so little to correlate afterwards. - A check from outside your network. The one thing that reliably catches this, if you run one. - Alerting. Depends on whether a CPU threshold exists and where it sits. - On-call. Follows from the above. Nothing crosses a threshold, nobody is paged. Purple marks what only a test on your own infrastructure can settle. The rest follows from how the attack works, not from how well your team configured things. Zone 3 is unusual here. The signal exists, on a CPU graph most teams already have. The question is whether anyone ever wired it to an alert. ## What you control, and how this differs from a TCP connection flood Obsidio exposes four parameters, and two of them change the character of the run: - Concurrent handshakes per worker. Twenty by default, adjustable from one to a hundred. It scales the simultaneous handshake load linearly. - Idle timeout. One millisecond by default. At that setting the socket is destroyed almost the instant the secure connection is established, so the server pays the crypto cost and the client leaves. Raise it and sockets are held longer, occupying ports and file descriptors at the price of a lower handshake rate. You are choosing between CPU pressure and connection-table pressure. - Think time. A pause between handshakes within each slot, zero by default. It paces the run down linearly when you want a sustained level rather than a peak. - Port. Defaults to 443. Certificate validation is off on the client side, so an expired or self-signed certificate on a test endpoint will not abort the handshake. The two attacks sit in the same category and behave nothing alike. A TCP connection flood does no negotiation beyond the TCP handshake, sends no payload, and holds each idle socket for minutes. Its target is your connection table: file descriptors, connection-tracking entries, the accept queue. A TLS flood is the mirror image. Its sockets live for milliseconds and its target is your processor. Generous connection limits with a modest CPU fail the TLS flood and shrug off the connection flood, and a fast CPU behind a tight file-descriptor limit does the reverse. Running one and calling the category covered is how that gets found late. ## How to defend against a TLS flood Where TLS terminates decides almost everything, so start there. - Terminate TLS somewhere built to absorb handshakes. A CDN or managed load balancer splits the path in two. Cloudflare’s Full mode documents this shape: HTTPS between the visitor and Cloudflare, with Cloudflare making its own connection to the origin. AWS documents the same structure for an Application Load Balancer, which “maintains two connections: one connection with the client and one connection with a target”. The usual caveat applies: a proxied site whose origin IP still answers on 443 is not protected, only obscured. - Do not file session resumption under mitigation. It is a performance feature and does nothing here. RFC 8446 explains why: resumption uses a pre-shared key identity the server issued after a handshake had already completed, and only then can the derived key “bootstrap the cryptographic state instead of a full handshake”. A connection with no prior session has nothing to present. nginx ships ssl_session_cache none, ssl_session_timeout 5m and ssl_session_tickets on, all of which govern returning users, not your defensive posture. - Check which layer your connection limits live at. This is the one most likely to be quietly wrong. nginx ships two per-source connection limiters. The HTTP one counts a connection only once a full request header has been read, so it never sees this traffic. The stream-level equivalent, available since nginx 1.9.3, counts connections per key without that condition. If your only per-source cap is the HTTP one, it is not in this path. - Measure your handshake headroom, because nobody can quote it to you. Handshakes per second depends on your certificate key type, cipher selection, processor and whether offload hardware is in the path. We found no published figure worth repeating and will not invent one. One related default: nginx’s stream ssl_handshake_timeout is sixty seconds, which bounds slow handshakes and does nothing about fast ones. ## What you can check yourself, and what it will get wrong Several of these you can answer today without help. It is worth knowing where a cheap check misleads you. Read the configuration. Establish where TLS terminates, whether your origin answers directly on its own IP, and whether your per-source connection limit sits at the HTTP layer or below it. This takes an afternoon and it tells you the design is sound. It does not tell you the processor holds. Test alert routing on its own. Fire a synthetic CPU alert and see whether it reaches the right rotation and whether anyone acts. That verifies the plumbing and needs no attack traffic. Run a single-source test against a staging environment, with change-management sign-off, on infrastructure you own. This is legitimate and useful. It is also where the trap sits. A test from one machine does not merely fail to answer the Zone 1 questions. It answers several of them wrongly, in a reassuring direction. Your per-source connection limit catches one address immediately. Reputation filtering handles a datacenter IP without breaking stride. The asymmetry works against you too: one client’s processor caps how many handshakes it can initiate, so the peak you reach says more about your test machine than your defenses. Every control in Zone 1 appears to hold, and you conclude you are covered. Then real traffic arrives from thousands of residential addresses across dozens of countries, no single source doing anything remarkable, and those same controls behave completely differently, because they key on source concentration and traffic realism. One machine reproduces neither. The cheap check produces a false pass on the controls you most need to trust, and a synthetic alert cannot tell you whether anyone would have read a rising processor curve as an attack rather than a bad deploy. ## How Obsidio tests a TLS flood Authorization comes first. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually, and any run can be aborted live. You choose the concurrency, the idle timeout and the pacing. Load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, so a per-source cap gets tested the way distributed traffic would test it. Two things to watch: - Handshakes per second, not request rate. Each completed handshake counts as one request in the report, so the rate figure here is a handshake rate. Compare it against whatever headroom you measured beforehand. - Post-handshake connection counts. Active and peak connections show how many sockets sit between handshake completion and teardown. At the default idle timeout that stays low even at full pressure, and a low count alongside a high handshake rate is the signature of this attack rather than a connection flood. The split is worth stating plainly. Obsidio reports how many handshakes completed, how many failed, how your edge controls responded and what the connection counts did, because all of that is visible from outside. Whether the processors on your TLS terminators saturated, whether your SIEM recorded anything and whether anyone was paged live only on your own consoles. Have someone watching them during the window, or those questions go home unanswered. Strength is proven, not promised. A TLS flood does not ask your server for anything. It asks it to prove who it is, thousands of times over, and then walks away without a word. ## Where this fits in a testing programme TLS Flood belongs in the connection-exhaustion category alongside TCP Connection Flood. Both bypass the application entirely, and between them they separate two failure modes teams habitually conflate. One exhausts the crypto path, the other the connection table. Testing only the second leaves your handshake capacity an open question, and no application-layer flood test closes it, because an HTTP flood amortises handshake cost across reused connections. The ten simulation types fail in genuinely different places. Slow attacks like Slowloris starve your connection pool by never finishing a request. A TLS flood finishes everything it starts and leaves. Coverage across the categories is the point, not volume in any one of them. For regulated institutions the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the result of a run is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized TLS flood simulation against your own infrastructure, see the Obsidio platform or get in touch. Independent, neutral, verifiable: resilience you can prove. ======================================== # RUDY Attack: How It Works and How to Test Your Defenses URL: https://obsidio.com/rudy-attack/ Published: 2026-06-30 A RUDY attack does not look like an attack. The request line is valid, the header block is finished, and the Content-Length tells the server exactly how many bytes are coming. That number is true. The only odd thing is how slowly the body arrives: one byte at a time, with a long pause between each one. That is what makes it harder to catch than Slowloris. Slowloris sends a request it never finishes, so anything waiting for a finished request notices something is missing. RUDY finishes the part your controls inspect and starves the part they do not. Your WAF finds nothing wrong, because on the evidence available to it, nothing is wrong. The short version - The request is valid, which is the whole problem. Complete headers, truthful Content-Length. A WAF sees a legitimate POST rather than an unfinished one, so inspection has nothing to flag. - One socket can pin a worker for days. A declared body of 100,000 bytes at one byte every ten seconds takes 1,000,000 seconds to finish, roughly 11.6 days. - An idle timeout does not stop it. nginx documents client_body_timeout (default 60s) as the limit between two successive reads, not on the body as a whole. A byte every ten seconds resets that clock. - The control that decides this is a minimum data rate on the body read. On Apache that is mod_reqtimeout, an extension module that does nothing unless it is loaded. - Watch held connections, not request rate. Each slot opens one socket and keeps it, so the rate graph reads near zero while the attack works. This is one post in a series covering each of the ten simulation types Obsidio runs. They fail in genuinely different places, which is why a test programme needs coverage across the categories rather than volume in one of them. For how they fit together, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDYyou are here Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a RUDY attack actually does RUDY, short for R-U-Dead-Yet, opens parallel HTTP POST connections and gives each one a complete request head: request line, Host, a content type, and a Content-Length stating the exact size of the body to follow. Then it delivers that body one byte at a time. The server does the only reasonable thing. It knows how many bytes are coming, it has received some, and the client is plainly still there, so it keeps the request handler assigned and waits. That handler, a thread or a worker slot, serves nobody else meanwhile. Multiply by a few hundred connections and the pool is gone. Real users get a timeout, not an error page. Think of twenty people filling out a long form at the counter, writing one letter every ten seconds. The clerk has to wait. They cannot move on until the form is done, and it is being done, just not this year. The arithmetic explains why nothing recycles. The default declared Content-Length is 100,000 bytes and the default gap between bytes is 10 seconds, so the body needs 1,000,000 seconds to complete, about 11.6 days. No socket in a realistic run gets there. Each slot holds its socket until the server tears it down or the run ends, so at 20 sockets per worker the wedged-request count is roughly 20 multiplied by the worker count, and it stays there. ## Which of your controls should have caught this It is worth walking the whole chain a request passes through, because the answer is rarely the control people expect. Three groups matter: what sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. Waits for a traffic spike. A byte every ten seconds is not one. - Firewall and WAF. The hard part. Headers are complete and the declared length is honest, so inspection sees a valid POST and passes it. It helps only if it buffers the whole body before forwarding, and plenty of deployments stream instead. - Rate limiting. Counts requests. Each source sends a handful, then goes quiet. - Bot detection and challenges. No page is ever loaded, so there is nothing to challenge. - CDN cache. A POST is not cacheable, so the cache is not in the path. Zone 2 What takes the hit? - Load balancer or reverse proxy. Absorbs the whole attack if it buffers request bodies, taking the connection cost itself. Worth confirming yours does. - Connection layer. Fills with sockets that are active, not idle. - Web server and application server. Where it bites. Handlers sit pinned waiting for a body unless a rate floor on the body read cuts them off. - Application and database. Never reached. The handler is stuck in front of them holding half a form. - Auto-scaling. Sees no load spike, so it never scales. Zone 3 Would you find out? - Dashboards. Requests per second look completely normal. - A check from outside your network. The one thing that reliably catches this, if you run one. - Logging and your SIEM. A request reaches the access log only once it ends, and then it looks like a client on a poor connection that timed out. - Alerting. Nothing crosses a threshold. - On-call. Nobody is paged. The service is down and the room is quiet. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. Zone 1 holds the difference between this attack and Slowloris. A WAF that waits for a complete request has a defensible reason to hold Slowloris traffic: the request is unfinished. RUDY takes that reason away. A control asked to decide whether this request is legitimate will decide it is, and be right. The only signal left is how fast the body arrives, and most request-inspection products have no opinion about that. ## What separates RUDY from Slowloris Five differences matter. Each points at a different control. - Where the request is incomplete. Classic Slowloris withholds the blank line that ends the header block, so the server stays parked in “reading request headers”. RUDY sends that block correctly and withholds the body instead. A header-read timeout catches the first and has no bearing on the second. - Whether the end of the body is declared. Slowloris has a slow-body variant, but it uses chunked transfer encoding and never sends the terminating zero-length chunk, so the body has no declared end. RUDY declares an exact length and honours it, slowly. No terminator is missing. - What runs out first. Slowloris targets the connection pool in front of your application. RUDY targets request handlers, because the server has accepted the request and committed a worker to it. - Which timeout decides it. A header-read timeout settles Slowloris. A body-read timeout settles RUDY, and only if it enforces a minimum transfer rate. - How it looks in a log. An unfinished Slowloris request often produces no entry. A RUDY request looks like an ordinary POST from a client on a bad line. There are only a handful of parameters. Sockets per worker defaults to 20 and runs from 1 to 100, setting how many handlers you are trying to pin. The gap between body bytes defaults to 10 seconds and ranges from 1 to 60: shorter recycles sockets more often, longer makes each one harder to time out but risks the server closing it for inactivity. The declared Content-Length defaults to 100,000 bytes and ranges from 1,000 to 10,000,000, fixing each socket’s lifetime alongside the interval. Host, Content-Type and Content-Length are forced and cannot be overridden. The truthful declared length is the mechanism, so letting it be changed would make this a different simulation. ## How to defend against a RUDY attack What decides this is a rule about how slowly a client may deliver a body it already promised. Three controls do the work; two popular candidates do not. - A minimum data rate on the body read. On Apache this is mod_reqtimeout, whose documented default is RequestReadTimeout handshake=0 header=20-40,MinRate=500 body=20,MinRate=500. The body setting allows at least 20 seconds, and the documentation states that whenever data is received the timeout is increased according to the minimum data rate, so 500 bytes buys one more second. A byte every ten seconds buys one five-hundredth of a second, so the allowance barely moves and the connection closes. Two caveats: the module has extension status and is inactive unless loaded, and the default body value sets no upper bound, so a client that really sustains 500 bytes per second keeps extending its timeout. - Do not rely on an idle timeout. nginx ships client_body_timeout 60s, and the documentation is explicit that it covers only the period between two successive read operations, not the whole body. A byte every ten seconds resets it indefinitely, and since the attacker picks the interval, no idle timeout long enough for real users is short enough to help. The control has the wrong shape for this attack rather than the wrong value. - A reverse proxy that buffers request bodies. nginx defaults to proxy_request_buffering on, documented as reading the entire request body from the client before sending the request to the proxied server, so your upstream is never contacted until the body is complete. Strong protection on two conditions: the origin cannot be reached directly, and the proxy holds that many connections cheaply. - Per-source concurrent connection limits. Ends a single-source attempt at once, does far less against load spread over thousands of addresses. - Body size caps will not save you. Apache’s LimitRequestBody defaults to 1073741824 bytes in current 2.4 releases, and was 0, meaning unlimited, in 2.4.53 and earlier. nginx defaults client_max_body_size to 1m. A declared 100,000 bytes passes both, and a tighter cap only recycles sockets sooner. ## What you can check yourself, and what it will get wrong Some of this you can settle today without help. It is worth knowing which parts, and where a cheap check misleads you. Read the configuration. Confirm whether a body-read timeout exists, whether it enforces a rate floor or only an idle gap, whether the module is loaded rather than merely available, and whether your proxy buffers bodies. That tells you the setting exists, not that it holds under concurrency. Test alert routing on its own. Fire a synthetic alert and watch whether it reaches the right rotation and whether anybody acts. That verifies the plumbing and needs no attack traffic. Run a single-source test against a staging environment, with change-management sign-off, on infrastructure you own. That is legitimate and useful, and it is also where the trap is. A test from one machine does not simply fail to answer the Zone 1 questions. It answers several wrongly, in a reassuring direction. Your per-source connection limit catches one address holding twenty sockets almost immediately, and reputation filtering handles a lone unfamiliar client. Every control in the front zone appears to work, so you conclude you are covered. Then a distributed version arrives from thousands of residential addresses holding a few sockets each, and those controls behave differently, because they key on source concentration rather than the behaviour doing the damage. The cheap check produces a false pass on the controls you most need to trust. ## How Obsidio tests a RUDY attack Whether your handler pool holds depends on how your proxy, web server, application server and connection limits interact under real concurrency, and that appears in no single config file. Obsidio runs RUDY as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually, and any run can be aborted live. You set the sockets per worker, the interval between bytes and the declared content length, then watch your stack. Because load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, a per-source connection cap gets tested the way a distributed attack would test it. Watch the right number. For RUDY that is active and peak held connections per bucket, because it counts how many handlers are wedged at any moment. The request-rate figure counts socket opens, and each slot opens one and keeps it, so the rate reads close to nothing. A team watching the rate graph will decide the test is not working while the handler pool empties underneath them. Be clear about the division of evidence. Obsidio reports how many connections were held and how your edge responded, because both are visible from outside. Whether your SIEM recorded anything, whether a dashboard moved and whether anyone was paged live only on your own consoles, so have someone watching during the window. Strength is proven, not promised. RUDY does not test your bandwidth. It tests whether anything in your stack has an opinion about how slowly a client is allowed to keep its promises. ## Where this fits in a testing programme RUDY and Slowloris are the two halves of the slow-attack category, and running one does not cover the other. Slowloris starves a header block and is answered by a header-read timeout. RUDY starves a declared body and is answered by a rate floor on the body read. Different settings, usually in different places, often owned by different teams. Neither is exercised by an application-layer flood test, so a programme built only on HTTP floods leaves this class unmeasured. The ten simulation types fail in genuinely different places. An HTTP flood inverts nearly everything above: the front defenses finally have something to act on, the damage reaches your database connection pool, and the detection problem flips from hearing nothing to drowning in alerts. Coverage across the categories is the point, not volume in one of them. For regulated institutions the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so a run leaves an artifact you can file rather than a screenshot you vouch for. To scope an authorized RUDY simulation against your own infrastructure, see the Obsidio platform or get in touch. Independent, neutral, verifiable: resilience you can prove. ======================================== # Apache Killer (CVE-2011-3192): How It Works and How to Test URL: https://obsidio.com/apache-killer-attack/ Published: 2026-06-24 Apache Killer is the rare denial-of-service attack that needs almost no traffic to work. One small GET request, carrying a Range header that asks for dozens of overlapping slices of the same file, can push a vulnerable Apache HTTP Server to allocate the response body in memory over and over until the process runs out of room. The flaw is old and it has a name and a number: CVE-2011-3192, disclosed in August 2011. That age is why it still belongs in a testing programme. The vulnerability is patched in every current Apache build, so the question is no longer “can this hurt me” but “am I actually running what I think I am running, everywhere, including the forgotten appliance and the vendor box nobody has rebuilt in years.” Apache Killer is a clean way to ask, because the server’s own reply is the answer. The short version - It is a memory attack, not a volume attack. The damage is per-request amplification of heap and resident memory, not gigabits or requests per second, so a low request rate can exhaust an unpatched server. - The weapon is a forced Range header. Each request asks for many overlapping byte ranges of one file, and a vulnerable server allocates a separate copy of the body for every range. - The affected versions are specific and known. Apache HTTP Server 1.3.x, 2.0.x through 2.0.64, and 2.2.x through 2.2.19. The fix shipped in 2.2.20 on 30 August 2011. - This is the one attack in the series a WAF can genuinely catch. The overlapping-range pattern is a fixed signature, not traffic that merely looks legitimate, so a tuned rule can block it before it reaches the server. - The response category is the finding. How your server answers a single crafted request tells you whether you are patched, whether something upstream is rejecting it, or whether you are exposed. This is one post in a series covering each of the ten simulation types Obsidio runs, one per attack. They fail in genuinely different places, which is the reason a test programme needs coverage across the categories rather than volume in one of them. For how they fit together and how to structure a first run, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killeryou are here Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What an Apache Killer attack actually does The HTTP Range header exists for a good reason. It lets a client ask for part of a file rather than the whole thing, which is how a paused download resumes and how a video player fetches only the segment it is about to play. A well-formed request says Range: bytes=0-1023 and gets back the first kilobyte, and the specification even lets a client ask for several ranges at once. Apache Killer abuses that last part. It sends a request whose Range header lists many overlapping byte ranges of the same file, something like bytes=0-1,5-1,5-2,5-3, and so on. A vulnerable server takes the list literally and allocates a separate buffer for every range in it. Because the ranges overlap and repeat, a tiny file gets materialised in memory many times over. The request costs the attacker almost nothing to send; the reply costs the server a multiple of the file size in heap and resident memory to assemble. That is why the attack behaves so differently from a flood. It does not lean on bandwidth or request rate. It leans on memory, so a handful of these requests in parallel can drive an unpatched httpd process into exhaustion while the traffic graph barely moves. The plain-language version: imagine ordering a single page from a librarian, but asking for it sliced into fifty mostly-overlapping pieces. The librarian photocopies the page fifty times to assemble your answer. Do that a few times at once and the librarian runs out of paper, even though you only ever asked about one page. ## Which of your controls should have caught this It is worth walking the whole chain a request passes through, because the answer here is unusual for this series. Three groups matter: what sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. Waits for a traffic spike. This attack does not produce one, so there is nothing for it to trigger on. - Firewall and WAF. The exception in the series, and worth saying plainly. The overlapping-range pattern is a known signature, not traffic that only looks legitimate, so a tuned rule genuinely can match it and block the request. That works only if the rule is present and current, and many deployments carry none. - Rate limiting. Counts requests. This sends far too few to cross a threshold, because the amplification is inside each request, not in their number. - Bot detection and challenges. It is a plain GET with no page load and no session to profile, so there is nothing to challenge. - CDN or fronting cache. A CDN that normalises or coalesces ranges shields the origin. One that forwards the Range header untouched does not. Worth confirming which yours does. Zone 2 What takes the hit? - Load balancer or reverse proxy. Absorbs the attack if it coalesces or rejects egregious range sets before forwarding. Worth confirming yours does rather than passing the header through. - Connection layer. Not the pressure point. The attack reuses a few connections and concentrates the load on memory, not sockets. - Web server. Where it bites, and only on a vulnerable Apache build. Resident memory climbs with every overlapping-range request until the process cannot allocate more. - Application and database. Never reached. The body is assembled in the server’s byte-range handling before any application logic runs. - Auto-scaling. Keys on request rate or CPU, neither of which spikes. Memory climbs quietly on one host, so a rate-based policy never scales. Zone 3 Would you find out? - Dashboards. Requests per second look normal, even low. The strain is in memory, which is not where most traffic dashboards point. - A check from outside your network. The single most useful signal here. The response to one crafted request tells you plainly whether you are patched. - Logging and your SIEM. These requests complete, so unlike a slow attack they do leave access-log entries. But nothing flags an odd Range header unless someone wrote a rule for it. - Alerting. Nothing crosses a request-rate or bandwidth threshold. - On-call. If the process runs out of memory, host-level monitoring may page someone for a crash or restart, even though nothing recognised the attack behind it. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. The picture here is less bleak than for most attacks in the series, and that is the honest point: a patched server and a tuned edge rule really can shut this down. The risk is not that the attack is unstoppable, but that you assume you are patched everywhere and have never proved it. ## The one request that tells you whether you are patched Apache Killer has an unusually clean diagnostic property. You do not need to overwhelm anything to learn where you stand. Send the crafted request and read the reply, because the response category maps directly to your state. A patched server refuses to play along. Faced with a set of overlapping ranges that would cost more than the file is worth, it ignores them and returns the complete file with a normal 200 response, or it rejects the request outright. An unpatched server does the dangerous thing: it returns a multipart range response with one part per requested range, which is the full amplification in action. A rejection by an upstream proxy or hardened stack, refusing the oversized header before it reaches the origin, is a third and equally informative outcome. Each is a different, readable answer to the same question. In the Obsidio simulation this is driven by two parameters. rangeCount is the amplification knob: it sets how many overlapping byte-range entries each request carries, and a vulnerable server allocates one response copy per entry. Its default is a deliberately mild 10, enough to demonstrate the effect without straining anything. Raise it in steps rather than jumping to the maximum, and watch which response category comes back at each one. A count in the hundreds stresses an unpatched server hard; a very large count may simply be refused by a modern stack, which is itself a useful signal. The second parameter, parallelRequestsPerWorker, defaults to 20 and sets how many run at once, multiplying the memory copies in flight without changing the per-request amplification. One detail matters for reading results: the Range header is computed from rangeCount and forced onto every request. You cannot override it, because it is the attack. Anything in your own headers sits alongside it. ## How to defend against Apache Killer Defence starts with the version number and works outward from there. Each layer is verifiable, which is the useful part. - Patch level, first and always. The fix for CVE-2011-3192 shipped in Apache HTTP Server 2.2.20 on 30 August 2011. Its changelog entry is exact: the server now handles byte-range requests using less memory, and “if the sum of all ranges in a request is larger than the original file, ignore the ranges and send the complete file.” A follow-up in 2.2.21 corrected a regression the first fix introduced. Any current Apache release is well past all of this, so the work is confirming that every server actually is current, appliances and vendor-shipped instances included. - Range-handling limits. Modern Apache exposes three directives that cap abusive range sets directly. MaxRanges limits the number of ranges before the server returns the complete resource instead, defaulting to 200. MaxRangeOverlaps caps overlapping ranges and MaxRangeReversals caps out-of-order reversals, both defaulting to 20. All three arrived in the 2.3.15 development line and are present in current stable builds. When a request exceeds a limit, the server sends the whole file rather than honouring the ranges, which removes the amplification. - A tuned WAF rule. Because the overlapping-range pattern is a fixed signature, a rule that recognises an abusive Range header can block the request before it reaches the origin. This is what makes Apache Killer the honest exception in this series. Worth having as a second line even on patched servers, but only as good as its currency. - Coalescing at the proxy or CDN. The HTTP specification itself says a server may ignore, coalesce, or reject range requests asking for more than two overlapping ranges or many small ranges out of order, because those signal a broken client or a deliberate denial-of-service attempt. A proxy or CDN that does this on your behalf shields the origin, provided the origin cannot be reached directly. Each of these is a setting or a version string somewhere, which means each can be stale, missing on one host, or overridden by a change nobody re-checked. ## What you can check yourself, and what it will get wrong Apache Killer is the one attack in this series where a self-check is genuinely worth a lot. Two checks you can run today: Read the version and the config. Confirm the Apache build on each host and check whether the range-handling directives are set. This tells you the setting exists and the version is current on the box you looked at. Send one request to staging and read the reply, with change-management sign-off on infrastructure you own. The diagnostic lives in the response itself rather than in whether the server fell over, so you learn the true state of that one endpoint immediately. The trap is not that the self-check misleads you about the endpoint you tested. It is what a single source cannot see. One request from one machine tells you nothing about the endpoints you did not think to test, and it is the forgotten ones, the legacy appliance and the unrebuilt vendor box, that carry the risk. Nor does it tell you whether anyone would notice memory climbing during a sustained run. A single request answers the version question. It does not answer the coverage question or the detection question, and those are the ones a real programme has to close. ## How Obsidio tests it Obsidio runs Apache Killer as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by a DNS TXT record before any traffic flows. Runs ramp up gradually, starting from the mild default range count and raising it in steps, and any run can be aborted live. You choose the range count and concurrency, then watch how each endpoint answers as the pressure rises. Because load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, your estate is probed the way a real attacker would, not from a single predictable source your filters would trivially catch. The thing to watch is the response category, not the request-rate graph, which stays low even while the attack is working. What matters is the mix of replies: a clean complete-file response or a rejection means that endpoint is holding, and a multipart range response means it is amplifying and exposed. Watching that mix shift as the range count climbs is the whole point of the run. There is an honest split in what a test can measure. Obsidio measures the response category and edge behaviour from outside, because those are visible from the client side of the connection. Whether resident memory actually climbed on the host, whether your SIEM recorded the burst of range requests, and whether anyone was paged when a process restarted are answers that live only on your own consoles. Have someone watching them during the window, so the internal and external pictures line up into one finding. Strength is proven, not promised. Apache Killer does not test your bandwidth. It tests whether the version you believe you are running is the version answering the request. ## Where this fits in a testing programme Apache Killer sits in the application-layer group alongside HTTP Flood, GoldenEye and Browser Flood, but it is the odd one of the four. The floods win on volume and hit request-processing capacity. Apache Killer wins on a specific implementation flaw and hits memory with almost no volume at all. A programme that only runs floods measures how much traffic your stack can take, but never asks the version-and-coverage question this attack answers, so that whole class of exposure goes unmeasured. For regulated institutions, the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the result of a run is an artifact you can file rather than a screenshot you have to vouch for. For an attack whose entire finding is which of your servers answered which way, a verifiable record of exactly that is worth having. To scope an authorized Apache Killer simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # Browser Flood: How It Works and How to Test Your Defenses URL: https://obsidio.com/browser-flood-attack/ Published: 2026-06-19 Most defenses against a layer 7 DDoS attack work by finding something a real browser would never do. A missing header. A TLS fingerprint no shipping Chrome produces. A client that asks for the HTML and then never fetches the stylesheet. Find the gap and you have something to act on. A Browser Flood closes that gap. It drives a real Chromium tab that loads your page, parses the HTML, fetches every stylesheet, script and image the page asks for, runs your JavaScript, fires your analytics, and then scrolls. Nothing is faked, so there is no gap to find. This is the case where “is this a real user?” has no clean answer, and it is where your bot mitigation has to earn its licence fee. The short version - Every request comes from a real rendering engine. Not a synthetic GET wearing a browser User-Agent string. Each counted request is one sub-resource a Chromium tab fetched because your markup asked for it. - One page load is roughly sixty requests. Your capacity plan was probably built per request. Your CDN absorbs the cheap part of that, and the document and the XHR calls arrive at your origin. - JavaScript challenges do not separate this from genuine traffic. A non-interactive challenge is passed by a browser processing the injected JavaScript, with no human involved. A real browser passes because it is one. - It is one of only two simulations that reach your database. Real page loads run your template rendering, session lookups and the endpoints behind your logged-in views. This is one of a series covering each of the ten simulation types Obsidio runs. They fail in genuinely different places, which is why a programme needs coverage across the categories rather than volume in one. For how they fit together, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Floodyou are here - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a Browser Flood actually does The simulation loads the target URL over and over with full browser semantics. Not only the main document, but the entire sub-resource graph: HTML, CSS, JavaScript, images, and every XHR or fetch call the page makes once its scripts run. On workers that expose a WebView runtime, Obsidio drives a real Chromium tab through puppeteer-core.connect() and lets the page issue every request a browser naturally would. That is the whole difference from an HTTP Flood, where a request is something the tool constructed and sent. Here a request is something the browser decided to make. After each load the worker takes one weighted in-page action: scroll half the time, click three times in ten, otherwise wait. The session in your analytics has a page view, a dwell time and an interaction, because all three happened. Think of a room full of ordinary-looking people opening your homepage again and again, scrolling, clicking links, running your scripts, rather than bots hammering one endpoint. ## Which of your controls should have caught this It is worth walking the whole chain, because the answer here is rarely the control people expect. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. There is volume to act on this time. Acting means deciding that a lot of real browser traffic is unwelcome. - Firewall and WAF. Well-formed GETs for URLs that exist. Nothing to match on. - Rate limiting. Per-IP counting has little to grip on traffic spread across thousands of devices, and any request budget must allow for a page load being tens of requests. - Bot detection and challenges. This is the control that decides the run, and nobody can predict it for you. Real browsers execute JavaScript challenges honestly, so what is left is fingerprinting and behavioural scoring. - CDN cache. Serves the static sub-resources from the edge. Cloudflare does not cache HTML or JSON by default, so the document and the XHR calls go through. Zone 2 What takes the hit? - Load balancer or reverse proxy. Handles a real concurrency increase, in the shape it was built for. - Connection layer. Not the target. Browsers open and close connections the way browsers do. - Web server. Serves every document request the cache handed on. - Application and database. This is where it bites, and one of only two simulations that get this far. Rendering, sessions and logged-in queries all run for real. - Auto-scaling. It will scale, because this looks like success. Whether that saves you or just bills you depends on what runs out first. Zone 3 Would you find out? - Dashboards. For once the graphs show it. Requests, page views and sessions all move, and your analytics counts the visits as visits. - A check from outside your network. Tells you whether real users can still get a page, which server-side latency will not. - Logging and your SIEM. No shortage of log lines, roughly sixty per page load. Finding the pattern in them is the work. - Alerting. Thresholds fire. The alert says traffic is up, which is also what a good day looks like. - On-call. Somebody gets paged, and the first hypothesis will be a marketing campaign. How long until the second one? Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. With a slow attack, that third zone fails silently. Here everything fires, and the question is whether anyone reads it correctly inside the first hour. ## Two execution paths, and why they are not interchangeable Browser Flood runs one of two ways, and knowing which one produced your report matters more than any parameter on the form. - The real browser path. With the WebView runtime available, exactly one Chromium tab per worker, driven over the DevTools protocol. Every reported request is one sub-resource the browser fetched. The parallel-loop and keep-alive settings are inert here, because the browser manages its own connections. - The HTTP fallback. Without that runtime the simulation drops to a parallel pool of plain GETs against the main URL only, twenty loops per worker by default, connection reuse on. No sub-resource fetching, no JavaScript, no in-page actions. A sensible degradation, and a different test: it cannot tell you how your bot mitigation scores honest browser traffic. Every worker holds a live Chromium instance, and browsers are expensive in memory, so Browser Flood buys fidelity rather than raw volume. Against modern edge defenses that is the better trade. The distinction from its siblings is clean. HTTP Flood sends the configured method, URL and body as-is, aimed at your request-processing path. GoldenEye reaches origin by force, appending randomized cache-buster parameters so the edge cache cannot answer. Browser Flood needs neither trick: it asks for the real resource graph, the cache answers what it can, and the rest arrives at origin, as it would for a genuine visitor. ## How to defend against a real-browser layer 7 DDoS attack Be sceptical of anyone offering one answer here, including us. Telling this traffic apart from real users is the whole difficulty, so every control below is partial. What follows is what the vendors document, including the limits they admit to. - Bot management, understood for what it is. Cloudflare’s bot score comes mostly from machine learning over headers, session characteristics and browser signals, plus heuristics matching known fingerprints. It is your strongest control here, and it produces a probability rather than a verdict. Cloudflare is candid about the edges: a new client’s first request generally carries no JavaScript Detections data, and JavaScript Detections does not guarantee a specific bot score. - Challenges, understood for what they are. A managed challenge picks its type from the signals the browser presents. A non-interactive challenge is resolved by the browser processing injected JavaScript, usually in under five seconds, with no human action. So it filters clients that cannot run JavaScript. It does not separate a browser under software control from one under a person. Interactive challenges do need a human, and Cloudflare advises against defaulting to them. - Know what your score threshold does. reCAPTCHA v3 returns a score for each request without user friction, and Google’s guidance is to act behind the scenes rather than block traffic. Sound advice, and it moves the decision to you: somebody has to have written down what each band does on each route. - Rate limit on something better than an IP. Cloudflare rate limiting rules can count on a cookie value, a header value, or a JA3 or JA4 TLS fingerprint instead of the source address. That is stronger, with the caveat that a real Chromium presents a real Chromium fingerprint. - Cache so your origin answers only what only it can answer. Cloudflare’s default cached types cover CSS, JS and the common image formats, and exclude HTML and JSON. Most of a Browser Flood therefore never reaches you, but the document rate and the API rate do. If your HTML is safe to cache at the edge, caching it changes this attack materially. If not, size your origin for the document rate and know that number in advance. One thing we will not claim: no vendor documentation we found says any single control reliably separates a real browser driven by software from one driven by a person. If a vendor says theirs does, that is a claim to test rather than a claim to file. ## What you can check yourself, and what it will get wrong Read the configuration. Which bot management mode is active, what each score band does, whether challenges cover the paths that matter, and what your cache rules do with HTML. That tells you what the settings say, not how they score real browser traffic. Rehearse the triage, not the alert. The problem here is interpretation, not silence. Show your on-call a graph of traffic up fortyfold with normal error rates and ask what they would do. It costs an hour and no traffic at all. Run a load test against staging, with change-management sign-off, on infrastructure you own. Legitimate and useful, and of every attack type in this series, this is where a cheap check misleads you most. A synthetic load generator sends the requests you tell it to send: a list of URLs, at a rate you choose, with a User-Agent string you type in. It does not parse your HTML to work out what the page needs. It does not run your JavaScript, so it never makes the XHR calls your dashboard depends on, and it produces none of the browser signals every detection engine above is built around. So the result is wrong in two directions at once. On detection it reads pessimistic: your synthetic client is exactly what bot management exists to catch, it gets caught, and you conclude you are covered against something you never sent. On capacity it reads optimistic: you sized your origin against requests that never touched your rendering path, while the real thing is sixty requests where you tested one, and the expensive sixtieth is a database query. Two errors pointing opposite ways is what makes this the worst false pass in the series. The test goes green, both halves of the reasoning are wrong, and nothing in the output says so. ## How Obsidio tests a Browser Flood Authorization comes before traffic. Domain ownership is verified by DNS TXT record before a single request is sent, runs ramp up gradually rather than starting at full load, and any run can be aborted live. Load comes from more than 100,000 globally distributed real devices, ethically sourced real hardware in real consumer networks. Realism is not a way around your controls, it is the only way to learn what they do when traffic is genuine. A defense validated only against obviously synthetic traffic is not validated. Three things worth watching during the window: - Separate your document rate from your total request rate. Cached sub-resources dominate the total. The number that predicts failure is uncached document requests per second at origin. - Watch the database, not the web tier. Connection pool saturation and query latency are usually where the ceiling sits. Keep the cache hit ratio and the scaling bill next to them. - Record what bot management decided. Not only whether requests were blocked, but the score distribution and the action taken. Be clear about what a report can prove. Obsidio measures how your edge responded and how connection counts behaved, because that is visible from outside your perimeter. Whether your SIEM correlated anything, whether an alert reached the right rotation, and whether the person who got it drew the right conclusion are answers only your own consoles hold. Have someone watching them while the run is live, because that half cannot be reconstructed later. Strength is proven, not promised. A Browser Flood does not ask whether you can absorb traffic. It asks whether you can tell the difference, and whether anyone would notice if you could not. ## Where this fits in a testing programme Browser Flood sits in the application-layer flood category with HTTP Flood, GoldenEye and Apache Killer, at the realistic end of it. Its closest relative is elsewhere: Puppeteer Script, the other simulation that reaches your database, runs a script you write against a real browser to exercise one flow such as a login. Browser Flood asks what many real browsers loading your page do to you. Puppeteer Script asks the same about one specific flow. Neither replaces the rest. An HTTP Flood concentrates load on your request-processing path without the browser overhead. Slowloris and RUDY never reach your application at all. Coverage across the ten simulation types is the point, not volume in one of them. For regulated institutions the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the outcome is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized Browser Flood simulation against your own infrastructure, see the Obsidio platform or get in touch. Independent, neutral, verifiable: resilience you can prove. ======================================== # GoldenEye Attack: How It Works and How to Test Your Defenses URL: https://obsidio.com/goldeneye-attack/ Published: 2026-06-16 The job of a CDN is to make sure most requests never reach your origin. A GoldenEye DDoS attack is built to make sure every one of them does. It appends a few randomised query-string parameters to each request, enough to make each one a brand new object as far as the cache is concerned. A cache that has never seen a URL has nothing to serve, so it goes to the origin and asks. That changes who is being tested. The edge keeps handling the traffic and keeps reporting healthy, while behind it your application servers render every page from scratch and your database answers every query, at a rate you sized assuming the cache would absorb most of it. Your CDN is working exactly as configured. It is just configured to read the attack as a very large number of visitors asking for very different things. The short version - It attacks your cache key, not your bandwidth. Two to five randomised parameters per request turn a hit into a miss, and a miss is a full origin round trip. - The damage lands deep in the stack. A slow attack stalls at your web server. This one reaches your application code and your database, because that is what a miss costs. - Whether it works is a config question with two opposite answers. nginx and Cloudflare put the query string in the cache key by default, so every busted URL is a miss. CloudFront’s CachingOptimized policy includes none, so the same URLs share one key. - Every request looks like a browser. A different real-world User-Agent each time, with DNT and Upgrade-Insecure-Requests on roughly half. A rule that blocks one bad user agent has nothing to hold on to. - Detection inverts. Every request is logged, so evidence is not the problem. Cache hit ratio names it, and that is rarely on the wall. This is one post in a series covering each of the ten simulation types Obsidio runs, one per attack. They fail in genuinely different places, which is why a test programme needs coverage across the categories rather than volume in one. For how they fit together and how to structure a first run, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEyeyou are here - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a GoldenEye DDoS attack actually does Obsidio’s GoldenEye simulation is a parallel-pool HTTP GET flood with one addition: before each request goes out, the target URL gets a fresh set of randomised query-string parameters. There are two to five of them, drawn from names that read as ordinary in a log file (cb, v, t, nocache and similar) plus two search-style keys such as q, page, ref or utm_source. Each request then gets a header overlay. With useRandomHeaders on, which is the default, the User-Agent is drawn per request from a pool of eight real desktop and mobile browser strings. DNT: 1 and Upgrade-Insecure-Requests: 1 are each added to roughly half of them, probabilistically, the way a mixed population of browsers behaves. A fixed set rides along on all of them: the Host, ordinary Accept values, and Cache-Control: no-cache. The header does less than it looks. A no-cache request is only a preference, in RFC 9111’s own words: it “indicates that the client prefers a stored response not be used to satisfy the request without successful validation on the origin server.” A cache may decline. The query string is different, because RFC 9111 builds the cache key from at least the request method and the target URI, and the URI carries the query. Changing it does not ask the cache to skip its copy; it asks for a resource the cache has no copy of. In plain terms: an HTTP flood where every visitor wears a different disguise and tweaks the order number on the way in, so the shop can never say “I already filled that one, here is the copy.” ## Which of your controls should have caught this Walk the whole chain, because the answer is rarely the control people expect. Three groups matter: what sits in front, what absorbs what gets through, and whether anything tells you. Zone 1 Should any of these have stopped it? - CDN and edge cache. The whole attack aims here, and one setting decides the run. nginx defaults proxy_cache_key to $scheme$proxy_host$request_uri, which carries the query string, so every busted URL is a guaranteed miss. Cloudflare’s default key includes the query string too. CloudFront’s managed CachingOptimized policy includes none, so the same traffic collapses onto one entry and never leaves the edge. Nobody can tell from outside which you are. - DDoS protection and scrubbing. Real volume this time, so a rate trigger has something to fire on. Whether it fires in time is the question. - Rate limiting. Thresholds apply, but a limiter keyed on the full URL sees every request as a different resource. - Bot detection and challenges. Rotation across eight genuine browser strings reduces header-matching rules to noise. Challenges fare better. - Firewall and WAF. Sees well-formed GET requests with nothing malicious in them, so there is no signature to match. Zone 2 What takes the hit? - Load balancer or reverse proxy. If it caches, it splits on the same key logic and inherits the answer. - Connection layer. Handshake churn on top of requests, since a fresh socket opens per request by default. - Web server. Busy, but rarely the constraint: requests complete and free their worker. - Application and database. Where it bites. Every miss is a full render: templates, sessions, queries. Capacity sized for cache-assisted traffic now serves all of it. - Auto-scaling. Sees real load and scales, which is both the intended behaviour and the invoice. Work out what an hour of that costs before you need to. Zone 3 Would you find out? - Dashboards. Requests per second climb, so there is something on the graph. Cache hit ratio names it, and that is two clicks away. - A check from outside your network. Edge response times can look respectable while origin requests queue behind them. - Logging and your SIEM. Everything lands in the access log. Grouping it is the hard part: every hit has a new user agent and an unseen URL. - Alerting. Depends on whether anything watches origin request rate or cache hit ratio, not just edge volume. - On-call. Somebody is paged if the alert exists. Whether the runbook mentions a cache-bypassing flood is worth reading first. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. The last group is the part teams discover late. A control that works but is invisible is still a finding. ## What separates it from a plain HTTP flood An HTTP flood attack and a GoldenEye run look alike on a bandwidth graph and behave nothing alike. HTTP Flood sends the configured method, URL and body exactly as given, with no randomisation, so an edge that caches the target URL absorbs it. GoldenEye differs in two places, and both matter for layer 7 DDoS mitigation: the cache-buster makes origin reach a property of the request, and the header randomisation leaves shape-based filters less to work with. The parameters are short: - parallelRequestsPerWorker, default 20, range 1 to 100. Concurrent loops per worker, roughly linear in cache-busted requests per second. The platform estimates five per second per loop, assuming the target answers within 200 ms. - useRandomHeaders, default true. On, a random browser User-Agent per request from the pool of eight. Off, everything is pinned to GoldenEye/1.0 and trivially fingerprintable, which is the point of the switch: use it to check whether your header-based rules fire at all. - headers, default empty. Merged with the fixed set and the overlays; anything you set pins its slot, so supplying DNT replaces the probabilistic overlay. Then there is keepAlive, false here and true for HTTP Flood, and that default is worth understanding. HTTP Flood pools sockets so the handshake is amortised and load concentrates on application threads and the database. GoldenEye has no such need, because cache-busted URLs reach the origin whether or not the socket is reused. Pooling buys nothing the attack did not already have, so paying the handshake every time folds connection setup into the load instead. Switch it on and origin reach survives; you stop stressing the handshake path. ## How to defend against a GoldenEye DDoS attack You cannot block the cache-buster, because you cannot enumerate names somebody might invent. The work is deciding which parameters may influence your cache key, and making sure the origin survives the rest. - Normalise the cache key. On Cloudflare, the Ignore Query String cache level drops query strings from the key and is available on every plan, including Free; per-parameter control lives in Cache Rules and is Enterprise. On CloudFront it is a cache policy choice: managed CachingOptimized includes no query strings and no cookies. On nginx, proxy_cache_key defaults to $scheme$proxy_host$request_uri; dropping the query means building it from $uri. - Allowlist the parameters rather than blocklisting them. Real traffic on a path uses a small, knowable set, and excluding the rest bounds the surface. Cloudflare caps a custom cache key at 100 parameters. The cost is correctness: two different responses can then share one entry, which breaks search, pagination and anything personalised. Do it per path, and enable Normalize URLs to origin alongside it, as Cloudflare’s guidance says, to avoid cache poisoning. - Bot management that does not depend on a header. A rule matching one user agent string is defeated by a pool of eight; challenges and behavioural signals survive rotation. This matters most where caching cannot help: Cloudflare does not cache HTML or JSON by default, so a flood at a dynamic page reaches origin whatever your key says. - Rate limit at the origin on identity, not on the URL. The URL is unique every time, so anything keyed on it counts to one. Key on source, session or normalised path, and keep the origin unreachable directly, because an exposed IP routes around every control above. ## What you can check yourself, and what it will get wrong Read the cache configuration, then send yourself a request carrying a junk parameter and read the cache status your CDN reports back. That is the cheapest useful hour here: it tells you what your key is, path by path. It does not tell you what your origin does when that key turns every request into a miss under concurrency. Test alert routing on its own. A synthetic alert verifies the paging plumbing with no attack traffic. Run a single-source test against staging, with change-management sign-off, on infrastructure you own. Legitimate, useful, and exactly where the trap sits. A test from one machine does not merely fail to answer the Zone 1 questions. It answers several of them wrongly, in a reassuring direction. Your per-IP rate limit catches a single source in seconds, bot detection flags one client hammering odd URLs, and reputation filtering handles the address. Every control in the front zone appears to work, you write “mitigated” in the notes, and the finding you needed is the one you did not get. Then the real thing arrives from thousands of residential addresses, none of which crosses a threshold on its own, and those controls behave differently, because they key on source concentration and traffic realism. One machine reproduces neither, and it cannot ask the question that decides the incident loudly enough: whether your origin holds when the cache hit ratio goes to nothing. ## How Obsidio tests a cache-bypassing flood Obsidio runs GoldenEye as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually, and any run can be aborted live. You choose the concurrency per worker, whether headers randomise and whether connections are reused. Because load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, per-IP limiting and reputation filtering meet the source spread a real attack has. Two metrics matter more than the rest: - Cache hit ratio. If it falls off a cliff when the run starts, the cache-buster is working and your origin is serving everything. If it holds, your key is normalising the parameters away and the edge is absorbing the attack, which is worth having on paper. - Origin request rate. The same story measured where it lands. Compare it with what your application tier is provisioned for, and watch database pool usage and query latency beside it. Plan for the detection questions too. Obsidio can report how your edge responded and what reached it, because that is measurable from outside. Whether your cache analytics showed the drop, whether your SIEM correlated anything and whether anyone was paged are answers only your own consoles hold, so have someone watching them during the window. Strength is proven, not promised. A high cache hit ratio protects you right up until someone sends a URL you have never seen before. ## Where this fits in a testing programme GoldenEye sits in the application-layer flood category, alongside HTTP Flood, Browser Flood and Apache Killer. Run it back to back with HTTP Flood and you isolate one variable: if HTTP Flood is absorbed and GoldenEye is not, the difference is your cache key. Slowloris inverts almost everything here: no volume for the front defenses to see, damage that stops at the connection pool, and silence instead of too much noise. That is the argument for coverage across the ten simulation types instead of volume in one. For regulated institutions the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the outcome of a run is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized GoldenEye simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # HTTP Flood Attack: How It Works and How to Test Your Defenses URL: https://obsidio.com/http-flood-attack/ Published: 2026-06-10 An HTTP flood attack contains nothing malformed. Every request is complete, valid, correctly framed HTTP, the kind your server was built to answer. Taken one at a time, they are indistinguishable from a customer checking a balance. Taken together, they are more work than your stack can do. So this is the one attack class where your front-line defenses finally have a signal to act on, which shifts the question. It is no longer whether DDoS protection can see the traffic. It is whether the threshold was set to the right number, whether the endpoint being hit is cacheable, and whether the smallest limit in your chain is the one you think it is. Configuration answers, all of them, and configuration goes stale quietly. The short version - Nothing about it is invalid. The load comes from sustaining a high number of concurrent in-flight requests, so there is no signature to match and no malformed field to reject. - The damage travels further than in any other class. It reaches past the web server to application threads and then the database connection pool, which is usually sized in the low hundreds. - Your edge controls are decisive here, not blind. Rate limiting, scrubbing and caching can all stop this. Whether yours do comes down to numbers in a config file. - Connection reuse changes what you are testing. Reusing sockets concentrates load on the request-processing path. Turning it off moves part of it back onto connection setup. - Detection fails by drowning rather than by silence. Log volume rises with request volume, which is how ingestion caps get hit, events get dropped and the alert that mattered arrives as one of four hundred. This is one in a series covering each of the ten simulation types Obsidio runs, one post per attack. They fail in genuinely different places, which is the reason a test programme needs coverage across the categories rather than volume in one of them. For how they fit together and how to structure a first run, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Floodyou are here - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowloris - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What an HTTP flood attack actually does Obsidio’s HTTP flood runs several independent request loops on each worker. A loop fires one request, waits for the response, and fires the next the moment it arrives. No pause, no think time, no randomization: the configured method, URL and body go out exactly as given, every time. The pressure comes from concurrency, not bandwidth. Twenty loops per worker across a run’s workers keeps a large number of requests in flight at the same moment, and each one occupies something on your side: a slot in the request queue, an application thread, a pooled connection, a query the database has to plan and run. A volumetric attack fills your pipe. This one fills your capacity to do work. Picture twenty people standing at a shop counter at once, each asking for the same item again the instant they are served. The shop never gets a break. Sending identical requests has one consequence worth naming: a cache in front of you can serve them. That is the useful part. If a plain repeated request never reaches origin, you have learned something real about your edge. If it reaches origin every time, you have learned something you can act on. ## Which of your controls should have caught this It is worth walking the whole chain a request passes through, because the answer is rarely the control people expect. Three groups matter: what sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. It has a real signal here, so it should act. Whether it does depends on thresholds set against your normal traffic. - Firewall and WAF. Sees complete, valid requests with nothing to match on. It contributes only where it also enforces a rate. - Rate limiting. Most likely to decide the outcome. What it keys on, the rate it allows and the burst it forgives are the whole answer. - Bot detection and challenges. Static agent string, no browser behaviour, so a challenge ought to catch it. Whether the hit endpoint sits behind one is the open part. - CDN cache. A cacheable path absorbs almost all of this. A login form or an API call reaches origin every time. Zone 2 What takes the hit? - Load balancer or reverse proxy. Forwards valid requests, because that is its job. Its upstream pool becomes an early ceiling. - Connection layer. Holds up well. Sockets open and retire normally, and with reuse on, a few carry many requests each. - Web server. Worker and thread pools saturate, and once they do, new requests queue instead of failing. - Application and database. This is where it bites. Requests cost CPU, and every query takes a connection from a pool far smaller than the request rate. - Auto-scaling. It sees the spike and reacts, the opposite of the slow-attack case. Whether it reacts fast enough, and whether more app servers on one database pool help, is what a test shows. Zone 3 Would you find out? - Dashboards. Requests per second climbs visibly. This is the attack your graphs are good at. - Logging and your SIEM. The inverse failure. Log lines multiply with request volume, so ingestion caps get hit, licence overage bites, events get sampled away, and the window you most need is the one that got truncated. - Alerting. Something fires. Whether it is one actionable alert or several hundred correlated ones is a tuning question only load answers. - On-call. Somebody gets paged, probably repeatedly. Whether the page says enough to act on is the part worth testing. - A check from outside your network. Reliable here. It settles whether users are affected while internal metrics are still being argued about. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. That third group is the part teams discover late. A control that works but is invisible is still a finding, and so is a control that reports more than anyone can read. ## The parameters, and the connection reuse tradeoff Five settings shape the run, and each moves the load somewhere different: - Parallel requests per worker. Default 20, adjustable from 1 to 100. Raising it raises concurrent load and achievable request rate roughly linearly. The platform estimates five requests per second per loop, assuming the target answers within 200 ms. - Method. Default GET, with POST, PUT, DELETE and HEAD available. A body is sent only on the non-GET, non-HEAD methods, so a large payload shifts cost toward upload bandwidth and body parsing. HEAD removes the response-body cost from both ends. - Payload. Empty by default. Placeholders such as {{uuid}} and sized random text expand per request, so bodies can differ while the request path stays constant. - Headers. Static headers on every request. The default sends only a user agent identifying the simulation, and anything can be overridden, which is how auth tokens and cookies get in. - Connection reuse. On by default. That last one deserves its own paragraph. With reuse on, a socket goes back to the pool after each response, so the next request skips the TCP and TLS handshake and the load lands almost entirely on request processing. Turn it off and every request opens a fresh socket: achievable rate drops and part of the load moves onto connection setup, which tests something else. Your server, not the client, decides how long a pooled socket survives. nginx defaults to keepalive_timeout 75s and keepalive_requests 1000, so a connection closes after a thousand requests or 75 idle seconds whatever the client would prefer. Pairing reuse with a server that answers Connection: close builds a pool torn down after every response, which is overhead on both sides. ## How this differs from GoldenEye and Browser Flood All three sit in the application-layer flood category and they are not interchangeable. GoldenEye appends randomized query-string parameters and rotates the user agent, so it reaches origin even behind a CDN and blunts header-based filtering. HTTP flood does the opposite on purpose: identical requests, so your cache is allowed to do its job and you get to measure whether it does. Browser Flood drives a real Chromium tab on each worker and fetches the whole sub-resource graph a browser requests. Run HTTP flood for raw request-processing capacity, GoldenEye to bypass the cache deliberately, Browser Flood for realistic user load. ## How to defend against an HTTP flood attack Defending against this is mostly arithmetic. Four things carry most of the weight: - Rate limiting with a burst you have actually chosen. On nginx that is limit_req_zone to define the key and rate, then limit_req zone=name burst=number where you apply it. The burst parameter defaults to 0, so nothing above the rate is forgiven, and rejected requests get a 503 by default via limit_req_status. Pick both values deliberately. - A concurrency cap alongside the rate cap. limit_conn limits simultaneous connections per key, which addresses a different failure than a request rate does. It also answers with a 503 by default. - Caching you have confirmed. nginx ships proxy_cache off, so caching exists only where somebody switched it on, and proxy_cache_lock also defaults to off, meaning concurrent misses on the same key each go to origin separately. Under a flood that turns one cold object into hundreds of origin requests. Switching the lock on collapses them into one. - Know the smallest number in your chain. nginx allows worker_connections 512 per worker process by default. Apache’s MaxRequestWorkers defaults to 256 on prefork and to 400 on the event and worker MPMs, which is ServerLimit of 16 times ThreadsPerChild of 25. PHP-FPM’s pm.max_children has no default at all, is mandatory, and caps simultaneous requests served. PostgreSQL’s max_connections is typically 100. Your real capacity is the lowest of those, and it is very often the database. Every value above lives in a file somebody edited once, which is why reading the config is weaker evidence here than running the attack. ## What you can check yourself, and what it will get wrong Three of these questions you can answer today without help. It is worth knowing which, and where a cheap check misleads you. Read the configuration and do the arithmetic. Write down the rate limit and its key, which paths are cached, the worker ceiling, the process pool, the database connection limit. The smallest number is your capacity. That tells you what the numbers are. It does not tell you the chain behaves the way the arithmetic suggests, because queuing, retries and timeouts interact in ways no config file shows. Test alert routing on its own. Fire a synthetic alert and see whether it reaches the right rotation and whether anyone acts. That verifies the plumbing, and it needs no attack traffic. It says nothing about how the same plumbing behaves when the volume is real. Run a single-source load test against a staging environment, with change-management sign-off, on infrastructure you own. That is legitimate, and for capacity curves it is genuinely useful. It is also where the trap is. One machine does not merely fail to answer the questions in the first zone. It answers several of them wrongly, in a reassuring direction. A per-source rate limit catches a single origin immediately, bot detection flags one client behaving oddly, reputation filtering handles it, and the edge gets declared sound. A real distributed flood does not present that way. Thousands of residential addresses each send a modest, plausible number of requests, no single source crosses any per-source threshold, and the aggregate lands on your origin regardless. The controls you most need to trust are the ones a single-source test grades too generously. Detection has the same asymmetry. A small test produces a trickle of logs, so it cannot say whether your ingestion cap gets reached, whether events start getting dropped, or whether the on-call engineer can find the useful alert among the rest. ## How Obsidio tests an HTTP flood Obsidio runs this as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually, and any run can be aborted live. You set the loops per worker, the method, the payload and whether connections are reused, then watch your stack. Load comes from 100,000+ globally distributed real devices, so per-source limits and reputation filtering get tested the way a distributed attack tests them. Three things to watch during the run: - Compare the counts along the chain. Requests accepted at the edge, requests reaching origin, requests completed successfully. Where those numbers diverge, a control is doing something, and the gap says more than any single figure. - Watch the database pool, not the CPU. Application CPU can look survivable while queries queue for a free connection. Pool utilization and queue depth show where the ceiling really is. - Measure from outside. Server-side metrics can read as degraded but acceptable while a real request from outside your network is timing out. Every request flows through a response analyzer, so each bucket report carries what the edge did: WAF responses, scrubbing behaviour, rate-limit rejections, captcha challenges. Obsidio measures that, because it is visible from outside. Whether your SIEM ingested the event and whether anyone was paged are answers only your own consoles hold, so have someone watching them during the window. Strength is proven, not promised. An HTTP flood does not look for a flaw in your code. It asks what the smallest number in your stack is, and whether anybody has checked it lately. ## Where this fits in a testing programme An HTTP flood is close to the exact inverse of Slowloris. The slow attack sends almost nothing, walks past volume-based defenses, stops at the web server’s connection pool, and produces silence where you would look for it. The flood is loud, gives your edge controls something to act on, reaches the database, and buries the finding in telemetry. Hardening for one teaches you little about the other. A programme built on floods alone leaves the slow class unmeasured, and one built on slow attacks alone never finds its capacity ceiling. For regulated institutions, the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the result of a run is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized HTTP flood simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # Slowloris Attack: How It Works and How to Test Your Defenses URL: https://obsidio.com/slowloris-attack/ Published: 2026-06-05 A Slowloris attack can take a web server offline from a single laptop on a home connection. It sends almost no data, generates almost no requests per second, and looks nothing like the traffic spike your DDoS protection was bought to stop. That is the problem. Most defenses are tuned for volume: gigabits per second, requests per second, packets per second. Slowloris wins by sending as little as possible, very slowly, for as long as possible. If your protection keys on rate, this attack walks straight past it. The short version - It costs the attacker almost nothing. A successful run can be a few kilobytes per second from one machine, which is why volume-based defenses have nothing to trigger on. - It works by never finishing. Each connection sends part of a request and then trickles, so the server politely holds the connection open waiting for the rest. - There are four variants, and hardening against one does not cover the others. A header-read timeout stops the classic version and does nothing for the slow-read variant. - Your DDoS protection and WAF probably are not what decides this. The outcome usually comes down to your web server timeouts and whether your proxy buffers requests. - It is invisible where you would look. Requests per second read normal, and unfinished requests often never produce a log line at all. This is the first in a series covering each of the ten simulation types Obsidio runs, one per attack. They fail in genuinely different places, which is the reason a test programme needs coverage across the categories rather than volume in one of them. For how they fit together and how to structure a first run, start with our guide on how to test your DDoS protection. The ten simulation types One post each, grouped the way the platform groups them. Application-layer floods - HTTP Flood - GoldenEye - Browser Flood - Apache Killer Slow attacks - Slowlorisyou are here - RUDY Connection exhaustion - TLS Flood - TCP Connection Flood Protocol-specific and scripted - DNS Floodcoming soon - Puppeteer Scriptfunctional load, not an attack ## What a Slowloris attack actually does Slowloris opens many parallel TCP connections to a web server and then refuses to finish any of them. Each connection sends the beginning of an HTTP request (the request line, a Host header) and then trickles one more header line every few seconds. The terminating blank line that tells the server “the request is complete, you may now process it” never arrives. The server does the reasonable thing: it waits. It holds the connection open, keeps a worker or a slot in the connection pool assigned to it, and waits for the rest of a request that will never come. Multiply that by a few hundred connections and the pool is full. Legitimate users then get a timeout, not an error page, because the server never gets far enough to serve them. Think of twenty people phoning a shop, each starting to place an order and then stretching every sentence out so the call never ends. The staff are polite, so they stay on the line. Nobody else can get through. The technique is not new. The original Slowloris tool was released on 17 June 2009, and it still works, because the thing it exploits is not a bug. It is the assumption, built into how HTTP servers handle connections, that a client which has started talking intends to finish. ## Which of your controls should have caught this It is worth walking the whole chain a request passes through, because the answer is rarely the control people expect. Three groups matter: what sits in front, what absorbs whatever gets through, and whether anything tells you it happened. Zone 1 Should any of these have stopped it? - DDoS protection and scrubbing. Waits for a traffic spike. There is not one. - Firewall and WAF. Inspects complete requests, and this one never completes. It helps only if it buffers the full request before passing it upstream, and plenty of deployments do not. - Rate limiting. Counts requests. This sends far too few to cross a threshold. - Bot detection and challenges. Never loads a page, so there is nothing to challenge. - CDN cache. Nothing cacheable is in play, so it makes no difference either way. Zone 2 What takes the hit? - Load balancer or reverse proxy. Absorbs the whole attack if it buffers requests. Worth confirming that yours does. - Connection layer. Fills with held-open sockets. - Web server. This is where it bites. Worker slots run out unless your timeouts and a minimum transfer rate cut the connections off first. - Application and database. Never reached. The attack stops earlier. - Auto-scaling. Sees no load spike, so it never scales. Zone 3 Would you find out? - Dashboards. Requests per second look completely normal. - A check from outside your network. The one thing that reliably catches this, if you run one. - Logging and your SIEM. Unfinished requests often produce no access-log entry, so there may be nothing to correlate afterwards. - Alerting. Nothing crosses a threshold. - On-call. Nobody is paged. The service is down and the room is quiet. Purple marks what only a test on your own infrastructure can settle. Everything else follows from how the attack works, not from how well your team configured things. That last group is the part teams tend to discover late. A control that works but is invisible is still a finding, and so is a control that fails without anyone noticing. ## Four vectors, four different failure modes “Slowloris” is often treated as one attack. In practice, holding a connection open has several distinct forms, and a server or proxy hardened against one can still be exposed to another. Obsidio’s Slowloris simulation runs four: - Slow header. The classic. Sends GET /path HTTP/1.1 and a Host header, then trickles one header line per interval and never sends the terminator. The server stays parked in “reading request headers” state. - Slow POST. Sends a complete, valid POST header block with Transfer-Encoding: chunked, then trickles a one-byte chunk per interval and never sends the zero-length chunk that ends the body. Headers are finished, so a header-read timeout does not catch it. - Slow read. Sends a complete, entirely valid request, then stops reading the response. The client’s receive buffer fills, so the server’s send buffer backs up and the connection cannot be retired. Nothing about the request is malformed. The attack is on the read side. - Slow drop. Sends a valid keep-alive request, sits idle, then destroys the socket abruptly at random. This mixes reset-style churn into the connection table rather than steady occupancy, which stresses connection teardown and accounting instead of capacity. The distinction matters when you configure a fix. A header-read timeout stops slow header and does nothing for slow read. A body timeout stops slow POST and does nothing for either. Testing one vector and declaring the class handled is how teams end up surprised. ## Which servers are exposed Susceptibility comes down to architecture. Servers that dedicate a thread or process per connection run out of them; event-driven servers multiplex connections and degrade far more gracefully. Apache 1.x and 2.x are the canonical vulnerable case in the original disclosure, along with dhttpd and the Flask development server. Servers documented as resilient include nginx, lighttpd, Hiawatha, Cherokee and IIS. But “resilient architecture” is not the same as “safe deployment”: nginx still ships default timeouts of client_header_timeout 60s and client_body_timeout 60s, which is 60 seconds of free occupancy per connection, and an application server behind the proxy may have no such protection at all. Check what actually terminates the connection in your stack, not what the marketing page for one component says. ## How to defend against a Slowloris attack Mitigation is about refusing to wait indefinitely, and about limiting how much one client can hold. Four controls do most of the work: - Timeouts on partial requests. On Apache, mod_reqtimeout is the direct answer. Loaded, its defaults are RequestReadTimeout handshake=0 header=20-40,MinRate=500 body=20,MinRate=500. That sets a minimum transfer rate, not merely a deadline, which is what actually kills a trickle. Confirm the module is loaded; availability is not the same as being active. - Minimum transfer rate, not only a timeout. A fixed deadline can be defeated by trickling just fast enough. A rate floor cannot. - Per-IP connection limits. Cap concurrent connections per source so one client cannot occupy a meaningful share of the pool. Effective against a single-source Slowloris, and much weaker against a distributed one, which is the case worth testing. - A buffering reverse proxy or CDN. A proxy that fully buffers the request before forwarding it absorbs the incomplete request on its own connection table and never wakes your origin. This is strong protection, provided the origin cannot be reached directly. A proxied site with an exposed origin IP is not protected. Each of these is a configuration value in a file somewhere, which means each of them can be wrong, stale, or overridden by a later change nobody re-checked. ## What you can check yourself, and what it will get wrong Three of those questions you can answer today without help. It is worth knowing which, and worth knowing where a cheap check misleads you. Read the configuration. Confirm the timeout module is loaded, look at the actual values, check whether your proxy buffers. This tells you the setting exists. It does not tell you the setting holds under concurrency, which is a different claim. Test alert routing on its own. Fire a synthetic alert and see whether it reaches the right rotation and whether anyone acts. That genuinely verifies the plumbing, and it needs no attack traffic at all. Run a single-source test against a staging environment, with change-management sign-off, on infrastructure you own. This is legitimate and useful. It is also where the trap is. A test from one machine does not merely fail to answer the earlier questions. It answers several of them wrongly, in a reassuring direction. Your per-IP connection limit catches one source immediately. Bot detection flags a single odd client. Reputation filtering handles it. Every control in the first group appears to work, and you conclude you are covered. Then a real distributed attack arrives from thousands of residential addresses and those same controls behave completely differently, because they key on source concentration and traffic realism, which is exactly what one machine cannot reproduce. The cheap check produces a false pass on the controls you most need to trust. The same asymmetry applies to detection. A synthetic alert proves the routing works. It cannot tell you whether your dashboards show anything during an actual slow attack, or whether your logging captures it, because those failures depend on the traffic being real. ## How to test whether your Slowloris defense works You cannot infer this from a configuration review. Whether the pool actually holds depends on the interaction between your proxy, your web server, your application server and your connection limits under real concurrency, and that interaction is not visible in any single config file. Obsidio runs Slowloris as a controlled, authorized simulation against infrastructure you own. Domain ownership is verified by DNS TXT record before any traffic flows, runs ramp up gradually, and any run can be aborted live. You choose the vector, the number of sockets held per worker, and the trickle interval, then watch what your stack does. Because load comes from 100,000+ globally distributed real devices rather than a handful of datacenter instances, a per-IP connection cap gets tested the way an actual distributed attack would test it. Two things to watch during the run, both of which trip people up: - Ignore the request-rate graph. For a slow attack, the rate figure counts connections opened, not throughput. It will look trivially low while the attack is succeeding. Watch concurrent held connections and peak connections instead. That is the metric that tracks whether the pool is filling. - Measure from outside. Server-side metrics can look calm while real users are timing out in the queue. Confirm the effect with an independent request from outside your own network. Plan for the detection questions too. Obsidio can report how your edge controls responded and how many connections were held, because that is visible from the outside. Whether your SIEM recorded anything and whether anyone was paged are answers only your own consoles hold, so have someone watching them during the window. Strength is proven, not promised. Slowloris does not test your bandwidth. It tests whether anyone has checked your connection timeouts since the day they were set. ## Where this fits in a testing programme Slowloris belongs in the slow-attack category, alongside RUDY, which starves a request body rather than a header block. Both probe connection handling and timeout configuration. Neither is covered by an application-layer flood test, which is why a programme that only runs HTTP floods leaves this whole class unmeasured. The ten simulation types fail in genuinely different places. An HTTP flood inverts almost everything above: the front defenses finally have something to act on, the damage travels as far as your database connection pool, and the detection problem flips from hearing nothing to drowning in alerts. Coverage across the categories is the point, not volume in any one of them. For regulated institutions, the test also has to leave a record. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA and NIS2, generated inside Trusted Execution Environments, so the result of a run is an artifact you can file rather than a screenshot you have to vouch for. To scope an authorized Slowloris simulation against your own infrastructure, see the Obsidio platform or get in touch with the team. Independent, neutral, verifiable: resilience you can prove. ======================================== # How to Test Your DDoS Protection URL: https://obsidio.com/how-to-test-ddos-protection/ Published: 2026-05-29 Most teams learn the limits of their DDoS protection during a real attack. That is the worst possible time to find out that a WAF rule was too loose, or that an origin server was never shielded at all. Knowing how to test your DDoS protection before an incident is the difference between a controlled finding and a public outage. This guide is written for the people who own that risk at a regulated institution: security engineers, WAF and load-balancer operators, and the compliance officers who have to prove resilience to a regulator. It covers what a proper test measures, how to run one without knocking yourself offline, and how to turn the result into evidence an auditor will accept. ## What testing your DDoS protection actually means A DDoS test sends controlled, realistic attack traffic at infrastructure you own, then measures whether your defenses absorb it and how your service behaves while under load. The goal is not to break the site. It is to find the point where protection degrades, so you can fix it on your own schedule. Two things it is not: - It is not a booter or stresser. Those services fire anonymous traffic at arbitrary targets. They are illegal to point at anything you do not own, and they give you no measurement, no authorization trail, and no report. - It is not ordinary load testing. A load test asks “can we serve 10,000 legitimate users?” A DDoS test asks “what happens when the traffic is hostile, malformed, or shaped specifically to exhaust a resource our load test never touches?” Different traffic, different failure modes. The value is in the specificity. A good test tells you which layer failed, at what volume, and whether your mitigation triggered in time. ## Authorization comes before the first packet The single rule that separates legitimate resilience testing from an attack is authorization. You test only assets you own or are explicitly contracted to test, and you prove that ownership before any traffic flows. Obsidio enforces this with DNS TXT ownership verification. You place a record on the domain you intend to test, and no simulation can start until that record is confirmed. Runs are controlled, ramped up gradually, and can be aborted live. This is what makes the exercise defensible to a legal team and repeatable for a compliance file: the authorization is recorded, not assumed. Treat this as the first control you are testing, not a formality. If your own change-management process cannot produce a signed-off, time-boxed authorization for a test, it will not produce one for an incident either. ## The attack types worth testing against DDoS is not one thing, and protection that stops one class can be blind to another. A test programme should exercise the distinct ways a service fails. Obsidio’s simulation catalog spans four categories, each stressing a different part of your stack: - Application-layer floods (Layer 7). HTTP Flood drives high volumes of well-formed requests at the application path: the request queue, the app threads, and the database behind them. Goldeneye appends randomized query strings so every request bypasses the cache and reaches the origin, with rotating browser-like headers. Browser Flood uses real browser sessions that load the full page and every sub-resource, producing traffic that is hard to separate from genuine users. Apache Killer sends overlapping Range headers (CVE-2011-3192) that force a vulnerable Apache build to allocate the response body many times in memory, a low-rate request that can exhaust an unpatched server. - Slow attacks. Slowloris holds many connections open by trickling partial requests, exhausting the connection pool at almost no bandwidth. RUDY opens slow POSTs that advertise a real content length then send the body one byte at a time, pinning request-handler workers. Both probe connection handling and timeout configuration, a common blind spot for volume-focused defenses. - Connection exhaustion. TLS Flood completes the full TLS handshake, making the server pay the asymmetric-crypto cost, then drops the socket. TCP Connection Flood opens raw connections and holds them idle to exhaust the connection table, file descriptors, and accept queue. These test capacity limits that a request-rate defense never sees. - Protocol-specific and scripted. DNS Flood sends raw DNS queries over TCP, one connection per query, stressing resolver CPU and TCP-listener resources. Puppeteer Script runs a scripted real-browser user journey (login, form submit, an end-to-end flow) under concurrency, for functional and synthetic-user load rather than raw request rate. The catalog grows as attacker techniques do. For a first test, aim for coverage across categories: at minimum one application-layer flood and one slow or connection-exhaustion attack, because they fail different parts of your stack. ## A method you can repeat: Configure, Test, Adapt, Retest A single test is a snapshot. Resilience is proven by the loop. Obsidio structures each run in four stages: - Authorize. Verify domain ownership via DNS TXT before anything runs. - Configure. Choose the simulation type, scale, geographic distribution, and duration. Start small: a low-intensity run confirms that your monitoring and your abort path work before you push volume. - Simulate. Run the controlled test from the distributed fleet while watching live metrics: requests per second, success rate, and data transferred. - Report. Export the result as an attested record of what happened. Then you adapt. Tune a WAF rule, adjust a rate limit, raise a timeout, and retest to prove the fix worked. The retest is the part teams skip and the part that matters most. A fix you did not verify under load is a hypothesis, not a control. ## What realistic traffic requires A test is only as honest as the traffic behind it. Defenses that key on obvious signatures, such as a single source subnet, a fixed user-agent, or datacenter IP ranges, will “pass” a test that uses those same tells, then fail against a real botnet that does not. Obsidio generates load from 100,000+ globally distributed real devices rather than virtualized instances, sourced from ethically sound providers. Traffic arrives from real hardware and smartphones across many networks and regions, so you are testing your defense against something that looks like a genuine distributed attack rather than a lab artifact your WAF can trivially filter. ## Turning a test into compliance evidence For a regulated institution, a passing test that leaves no record is worth little. The regulatory frameworks now expect the evidence, not just the effort. Under the EU’s Digital Operational Resilience Act (DORA), financial entities must run a resilience testing programme with, at minimum, appropriate tests of the ICT systems supporting critical or important functions each year (Article 24). Significant entities must also undergo advanced threat-led penetration testing at least every three years (Article 26). NIS2 obliges essential and important entities to adopt risk-management measures and test them, and FINMA expects Swiss institutions to manage operational resilience on a comparable basis. What these frameworks share is a demand for demonstrable, repeatable testing, the kind of assurance you can hand to an auditor or a board. Obsidio produces cryptographically attested, tamper-evident reports mapped to FINMA, DORA, and NIS2, generated inside Trusted Execution Environments so the result cannot be quietly edited after the fact. The output of a test becomes the artifact in your compliance file. Strength is proven, not promised. A test you can attest to is what turns “we are resilient” into something an auditor can check. ## Where to start If you have never tested your DDoS protection, begin with a single authorized, low-intensity application-layer run against a staging environment or a scheduled window. Watch how your monitoring and mitigation respond, then widen the scope from there. The first test rarely produces a clean pass, and that is exactly why you run it before an attacker does. To scope a controlled simulation against your own infrastructure, get in touch with the Obsidio team or request a demo. Independent, neutral, verifiable: resilience you can prove.