User Browser → API Gateway → Auth Service → Database
[untrusted] [semi] [trusted] [trusted]
↕
Payment Provider
[external]// nosec comments to suppress warnings. Velocity drops 30%.app.post('/search', (req, res) => { db.collection('users').find({ username: req.body.username, password: req.body.password }); });
{ "$gt": "" }{ username: "admin", password: { "$gt": "" } } which matches any non-empty password — the attacker logs in as admin without knowing the password. Fix: (1) Validate input types explicitly (if (typeof password !== 'string') reject). (2) Use a schema validator like Joi or Zod. (3) Use $eq operator explicitly. Classic SQL injection is caught by ORMs — NoSQL injection is the vector mid-level devs encounter today.app.post('/login', (req, res) => { const user = db.findUser(req.body.email); if (!user) { return res.status(401).json({ error: `No account found for ${req.body.email}` }); } if (!bcrypt.compare(req.body.password, user.hash)) { return res.status(401).json({ error: 'Incorrect password for this account' }); } });
is_admin: true field in their JWT token payload. The server accepts it without signature verification.FROM node:latest COPY . /app WORKDIR /app RUN npm install RUN npm run build USER root EXPOSE 3000 CMD ["node", "server.js"]
FROM node:latest — unpinned tag, could pull a compromised image. Pin to a specific digest. (2) USER root — container runs as root. Use a non-root user. (3) COPY . /app copies everything including .env, .git, node_modules. Use .dockerignore. Bonus: no multi-stage build — build dependencies ship to production.package-lock.json with 47 changed packages. The developer says: "Just ran npm update, everything passes tests."npm audit on the new lockfile — does it introduce new vulnerabilities? (3) Check changelogs for top-level dependencies. (4) Was this intentional or a side effect of npm update pulling transitive deps? "Tests pass" is necessary but not sufficient.import boto3 client = boto3.client( 's3', aws_access_key_id='AKIAIOSFODNN7EXAMPLE', aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', region_name='us-east-1' )
app.use(cors({ origin: '*', credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
origin: '*' with credentials: true is the most dangerous CORS config. It allows any website to make authenticated requests to your API — a textbook CSRF bypass. Fix: whitelist specific origins (origin: ['https://yourapp.com']). Never use wildcard with credentials.svc-analytics outside business hours. Source IP: 185.22.xx.xx (non-corporate range).val client = OkHttpClient.Builder() .hostnameVerifier { _, _ -> true } .build()
UserDefaults.standard.set(authToken, forKey: "user_token") UserDefaults.standard.set(refreshToken, forKey: "refresh_token")
UserDefaults is a plain plist file, not encrypted, accessible to anyone with physical device access or a backup. Auth tokens must go in the iOS Keychain (kSecClassGenericPassword). This is the #1 mobile storage mistake developers make.apiVersion: v1 kind: Pod metadata: name: payment-service spec: hostNetwork: true containers: - name: app image: mycompany/payments:latest securityContext: runAsUser: 0 privileged: true ports: - containerPort: 8080
runAsUser: 0 — runs as root inside the container. (2) privileged: true — full access to host kernel, can escape container. (3) hostNetwork: true — shares host's network namespace, bypassing network policies. (4) No resource limits — vulnerable to resource exhaustion DoS. Bonus: image: latest is unpinned.name: Build and Deploy on: pull_request_target: types: [opened, synchronize] permissions: write-all jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: some-org/deploy-action@main - name: Deploy env: AWS_KEY: ${{ secrets.AWS_ACCESS_KEY }} run: ./deploy.sh
permissions: write-all — violates least privilege. Scope to only what's needed. (2) some-org/deploy-action@main — unpinned third-party action. Pin to a specific commit SHA. (3) pull_request_target + secrets — this combination exposes secrets to code from forks. An attacker opens a PR, the workflow runs with repo secrets on their untrusted code.function Comment({ userInput }) { return <div dangerouslySetInnerHTML={{ __html: userInput }} />; }
{userInput} without dangerouslySetInnerHTML — React auto-escapes by default. (2) If HTML rendering is needed, sanitize with DOMPurify. This is the #1 frontend security mistake in React apps.resource "aws_security_group" "api" { name = "api-server" ingress { from_port = 0 to_port = 65535 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Environment = "production" } }
production — these aren't dev shortcuts. In production, every open port is attack surface. Infrastructure IS code — review it like code.