api-security — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited api-security (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Every API endpoint needs authentication, rate limiting, input validation, and proper CORS configuration.
Related: authentication, input-validation, access-control, security-context
Default to requiring auth. Explicitly mark public endpoints.
// WRONG — endpoint is open to anyone
app.get('/api/users', async (req, res) => {
res.json(await getUsers());
});
// RIGHT — require authentication
app.get('/api/users', requireAuth, async (req, res) => {
res.json(await getUsers());
});Prevent abuse and brute force attacks. Apply stricter limits to auth endpoints.
// WRONG — no rate limiting
app.post('/api/login', loginHandler);
// RIGHT — rate limited (stricter on auth routes)
app.post('/api/login', rateLimit({ windowMs: 15 * 60 * 1000, max: 5 }), loginHandler);
app.use('/api/', rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));Never allow all origins in production.
// WRONG — allows any website to call your API
app.use(cors({ origin: '*' }));
// RIGHT — whitelist specific origins
app.use(cors({
origin: ['https://yourdomain.com', 'https://app.yourdomain.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));Prevent denial-of-service via large payloads.
// WRONG — no size limit (default can be very large)
app.use(express.json());
// RIGHT — explicit size limit
app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ limit: '1mb', extended: true }));Internal errors reveal architecture to attackers.
// WRONG — sends stack trace to client
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message, stack: err.stack });
});
// RIGHT — generic message to client, full details to logs
app.use((err, req, res, next) => {
logger.error(err);
res.status(500).json({ error: 'Internal server error' });
});Reject requests with unexpected content types.
// WRONG — accepts anything
app.post('/api/data', handler);
// RIGHT — enforce expected content type
app.post('/api/data', (req, res, next) => {
if (!req.is('application/json')) {
return res.status(415).json({ error: 'Content-Type must be application/json' });
}
next();
}, handler);| Do | Don't |
|---|---|
| Require auth on all endpoints by default | Leave endpoints open accidentally |
| Rate limit (stricter on auth routes) | Allow unlimited requests |
| Whitelist CORS origins | Use origin: '*' in production |
| Limit request body size | Accept unlimited payload sizes |
| Return generic errors to clients | Send stack traces to clients |
| Validate Content-Type headers | Accept any content type |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.