Skip to content

Conversation

@ViktorPalchynskyi
Copy link

@ViktorPalchynskyi ViktorPalchynskyi commented Jan 29, 2026

Summary

Complete security stack for protecting web applications:

  • WAF (ModSecurity + OWASP CRS 4): SQL injection, XSS, command injection, path traversal, SSRF protection
  • CrowdSec: Log analysis and threat intelligence
  • Rate Limiting: Brute-force protection for auth endpoints
  • Container Hardening: Resource limits, security_opt, healthchecks

Changes

  • Docker-compose with nginx-waf, crowdsec, nginx-exporter, httpbin
  • Custom ModSecurity rules (SSRF, scanner detection, HTTP method restriction)
  • Nginx rate limiting for /api/auth/* endpoints
  • Makefile for automation (start, stop, test, logs, bans)
  • Security tests (30 tests) and false-positive tests (23 tests)
  • Documentation (README, QUICK_REFERENCE, EMERGENCY)

Test Plan

  • All 30 security tests pass
  • All 23 false-positive tests pass
  • Health checks work for all services
  • Resource limits applied correctly

Note

Medium Risk
Introduces new edge-security behavior (WAF rules and rate limiting) plus new Docker orchestration, which can block legitimate traffic or affect availability if misconfigured.

Overview
Adds a full Docker-based Nginx security stack via docker-compose.yml (ModSecurity/OWASP CRS WAF + CrowdSec + nginx-exporter, with optional loki/promtail/grafana and an httpbin default backend), including container hardening, healthchecks, and resource limits.

Introduces custom Nginx config (config/nginx/default.conf.template) implementing request rate limiting for auth and general API/GraphQL paths with a JSON 429 response, and adds custom ModSecurity rules plus exclusion rules to reduce false positives.

Adds operational tooling and guidance: a new Makefile, .env.example, tightened .gitignore, security and false-positive test scripts, and docs (README.md, docs/QUICK_REFERENCE.md, docs/EMERGENCY.md) plus a Prometheus scrape config snippet.

Written by Cursor Bugbot for commit 68ed348. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

cap_add:
- NET_ADMIN
- NET_RAW
network_mode: host
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CrowdSec bouncer cannot reach LAPI endpoint

Medium Severity

The crowdsec-bouncer service is configured with network_mode: host and CROWDSEC_LAPI_URL=http://crowdsec:8080. With host network mode, Docker DNS resolution doesn't work, so the hostname crowdsec cannot be resolved. Additionally, CrowdSec only exposes port 6060 (metrics) to the host, not the LAPI port 8080. When the bouncer profile is enabled, the bouncer will fail to connect to CrowdSec.

Additional Locations (1)

Fix in Cursor Fix in Web

# ===== RATE LIMITING ZONES =====

# OTP/Login endpoints (strict - 5 req/min)
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/m;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it per IP?

PROXY_SSL_CONFIG

# Auth endpoints (strict rate limiting)
location ~ ^/api/auth/(login|verify-otp|send-otp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually have such endpoints in production:

Suggested change
location ~ ^/api/auth/(login|verify-otp|send-otp) {
location ~ ^.*?/api(?:/[^/]*)*/[^/]*(?:login|sign-?in|register|sign-?up|verify|otp)[^/]*(?:/.*)?$ {

PROXY_SSL_CONFIG

# Auth endpoints (strict rate limiting)
location ~ ^/api/auth/(login|verify-otp|send-otp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need same regex update

Comment on lines +1 to +3
# Nginx Security Stack

Docker-based security stack: WAF (ModSecurity + OWASP CRS), CrowdSec, Rate Limiting.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Nginx Security Stack
Docker-based security stack: WAF (ModSecurity + OWASP CRS), CrowdSec, Rate Limiting.
# Cloud Native Nginx
Nginx-based security stack for protecting web applications, focused on resolving [OWASP Top 10](https://owasp.org/www-project-top-ten/) security risks out of the box, with minimal configuration.
## Features
- Solution focused on decreasing false positives to minimize security impact on business operations.
- Includes WAF (ModSecurity + OWASP CRS 4) that prevent from common threats like SQL injection, XSS, command injection, path traversal, SSRF protection
- CrowdSec - Log analysis and threat intelligence
- Rate Limiting - Brute-force protection for auth endpoints
- Container Hardening - Resource limits, security_opt, healthchecks


Docker-based security stack: WAF (ModSecurity + OWASP CRS), CrowdSec, Rate Limiting.

## Quick Start
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I not really get what process Cloudbankin team should follow to setup it properly. Does them need to clone repo on production VM and run make start? Or them need just copy docker-compose.yaml and run docker up?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants