security

# Run audit pnpm audit

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "security" with this command: npx skills add sgcarstrends/sgcarstrends/sgcarstrends-sgcarstrends-security

Security Skill

Dependency Scanning

pnpm audit

Run audit

pnpm audit

Only high/critical

pnpm audit --audit-level=high

Auto-fix

pnpm audit --fix

JSON report

pnpm audit --json > audit.json

Fix Vulnerabilities

Direct dependencies: Update version in pnpm-workspace.yaml catalog

Transitive dependencies:

Find dependency chain

pnpm why vulnerable-package

Use overrides as last resort

package.json

{ "pnpm": { "overrides": { "vulnerable-package": "^3.1.0" } } }

Snyk

snyk auth # Authenticate snyk test # Test for vulnerabilities snyk monitor # Monitor for new vulnerabilities snyk fix # Auto-fix

OWASP Top 10 Checks

  1. Broken Access Control

// ❌ No authorization export async function deletePost(postId: string) { await db.delete(posts).where(eq(posts.id, postId)); }

// ✅ With authorization export async function deletePost(postId: string, userId: string) { const post = await db.query.posts.findFirst({ where: eq(posts.id, postId) }); if (post.authorId !== userId) throw new Error("Unauthorized"); await db.delete(posts).where(eq(posts.id, postId)); }

  1. Injection Prevention

// ❌ SQL Injection const query = SELECT * FROM users WHERE id = ${userId};

// ✅ Parameterized query (Drizzle ORM) const user = await db.query.users.findFirst({ where: eq(users.id, userId) });

  1. XSS Prevention

React escapes content by default. When rendering HTML:

  • Sanitize with sanitize-html library before rendering

  • Never render untrusted content directly

  1. Rate Limiting

import { Ratelimit } from "@upstash/ratelimit"; import { redis } from "@sgcarstrends/utils";

const ratelimit = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(5, "15 m"), });

export async function login(email: string, password: string, ip: string) { const { success } = await ratelimit.limit(ip); if (!success) throw new Error("Too many login attempts"); return verifyCredentials(email, password); }

  1. Password Security

import bcrypt from "bcrypt";

// ✅ Hash passwords const hashedPassword = await bcrypt.hash(password, 10);

// ✅ Strong password validation const passwordSchema = z.string() .min(12) .regex(/[A-Z]/, "Must contain uppercase") .regex(/[a-z]/, "Must contain lowercase") .regex(/[0-9]/, "Must contain number") .regex(/[^A-Za-z0-9]/, "Must contain special character");

  1. SSRF Prevention

// ❌ SSRF vulnerability export async function fetchUrl(url: string) { return await fetch(url); }

// ✅ Whitelist approach const ALLOWED_DOMAINS = ["api.example.com", "data.gov.sg"];

export async function fetchUrl(url: string) { const parsedUrl = new URL(url); if (!ALLOWED_DOMAINS.includes(parsedUrl.hostname)) { throw new Error("Domain not allowed"); } return await fetch(url); }

Input Validation

import { z } from "zod";

const userInputSchema = z.object({ name: z.string().min(1).max(100), email: z.string().email(), age: z.number().int().min(0).max(150), });

export async function createUser(data: unknown) { const validated = userInputSchema.parse(data); // Now safe to use }

CORS Configuration

// ❌ Too permissive app.use(cors({ origin: "*" }));

// ✅ Whitelist specific origins app.use(cors({ origin: [ "https://sgcarstrends.com", "https://staging.sgcarstrends.com", process.env.NODE_ENV === "development" ? "http://localhost:3001" : "", ].filter(Boolean), credentials: true, }));

Security Headers

// next.config.js const securityHeaders = [ { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" }, { key: "X-Frame-Options", value: "SAMEORIGIN" }, { key: "X-Content-Type-Options", value: "nosniff" }, { key: "X-XSS-Protection", value: "1; mode=block" }, { key: "Referrer-Policy", value: "origin-when-cross-origin" }, ];

module.exports = { async headers() { return [{ source: "/:path*", headers: securityHeaders }]; }, };

Environment Variables

// ❌ Hardcoded secret const apiKey = "sk_live_EXAMPLE_NOT_REAL";

// ✅ From environment with validation import { z } from "zod";

const envSchema = z.object({ API_KEY: z.string().min(1), DATABASE_URL: z.string().url(), });

const env = envSchema.parse(process.env);

CI Integration

.github/workflows/security.yml

name: Security Audit

on: push: branches: [main] schedule: - cron: '0 0 * * 1' # Weekly

jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 - run: pnpm install - run: pnpm audit --audit-level=high

Security Checklist

  • All user input validated (Zod schemas)

  • SQL injection prevented (using ORM)

  • XSS prevented (React escaping, sanitization)

  • Authentication implemented correctly

  • Authorization checks in place

  • Passwords hashed (bcrypt/argon2)

  • Rate limiting configured

  • Security headers set

  • CORS configured properly

  • HTTPS enforced

  • Dependencies audited (pnpm audit)

  • Secrets in environment variables

  • Error messages don't leak info

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

Voidly Agent Relay

Give agents encrypted private messaging — send, receive, discover, and call other AI agents with post-quantum E2E encryption. No API key needed. Zero config.

Registry SourceRecently Updated
1783Profile unavailable
Security

Agent Security Skill Scanner

AI Agent 技能安全扫描器 - 检测恶意技能、后门代码、权限滥用 (Beta 版本)

Registry SourceRecently Updated
711Profile unavailable
Security

agent-bom

Security scanner for AI infrastructure and supply chain — discovers MCP clients and servers, scans for CVEs, maps blast radius, generates SBOMs, runs CIS ben...

Registry SourceRecently Updated
8180Profile unavailable
Security

Session Password

Provides secure session authentication using bcrypt-hashed passwords, security questions, email recovery, and lockout protection with audit logging.

Registry SourceRecently Updated
421Profile unavailable