Assumption: Node.js + Express, bcrypt password hashes, and a server-side session store. ```ts import express from "express"; import cors from "cors"; import bcrypt from "bcrypt"; import rateLimit from "express-rate-limit"; const app = express(); app.use(express.json()); app.use(cors({ origin: ["https://app.example.com"], credentials: true, })); const loginRateLimit = rateLimit({ windowMs: 15 * 60 * 1000, limit: 10, standardHeaders: true, legacyHeaders: false, }); app.post("/login", loginRateL...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add HoangNguyen0403/agent-skills-standard --skill common-owasp --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Common Owasp?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hoangnguyen0403-common-owasp-d9a226f9)More formats (shields.io, HTML) on the badges page.
Assumption: Node.js + Express, bcrypt password hashes, and a server-side session store.
```ts
import express from "express";
import cors from "cors";
import bcrypt from "bcrypt";
import rateLimit from "express-rate-limit";
const app = express();
app.use(express.json());
app.use(cors({
origin: ["https://app.example.com"],
credentials: true,
}));
const loginRateLimit = rateLimit({
windowMs: 15 * 60 * 1000,
limit: 10,
standardHeaders: true,
legacyHeaders: false,
});
app.post("/login", loginRateLimit, async (req, res) => {
const { email, password } = req.body ?? {};
if (
typeof email !== "string" ||
typeof password !== "string" ||
email.length > 320 ||
password.length < 8 ||
password.length > 128
) {
return res.status(400).json({ error: "Invalid credentials" });
}
// Parameterized query; select only fields required for authentication.
const user = await db.user.findUnique({
where: { email: email.trim().toLowerCase() },
select: { id: true, email: true, passwordHash: true },
});
// Use a valid bcrypt hash here to reduce account-enumeration timing leaks.
const hash = user?.passwordHash ?? process.env.DUMMY_BCRYPT_HASH!;
const passwordMatches = await bcrypt.compare(password, hash);
if (!user || !passwordMatches) {
return res.status(401).json({ error: "Invalid credentials" });
}
// Opaque session token; store its hash server-side.
const sessionToken = await sessionStore.create(user.id);
res.cookie("session", sessionToken, {
httpOnly: true,
secure: true,
sameSite: "lax",
maxAge: 8 * 60 * 60 * 1000,
});
// DTO projection: never return the raw ORM entity or passwordHash.
return res.status(200).json({
user: {
id: user.id,
email: user.email,
},
});
});
```
For authenticated resource endpoints, prevent IDOR/BOLA by filtering queries with both the requested ID and the authenticated user’s `owner_id`/`tenantId`. If JWTs are used instead of opaque sessions, require a short-lived token with `exp` and implement revocation on logout.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!