{"id":"3e3f45bd-ba8e-4b6a-b1fb-591eac123fc0","shortId":"tneeum","kind":"skill","title":"Cc Skill Security Review","tagline":"Antigravity Awesome Skills skill by Sickn33","description":"# Security Review Skill\n\nThis skill ensures all code follows security best practices and identifies potential vulnerabilities.\n\n## When to Use\n- Implementing authentication or authorization\n- Handling user input or file uploads\n- Creating new API endpoints\n- Working with secrets or credentials\n- Implementing payment features\n- Storing or transmitting sensitive data\n- Integrating third-party APIs\n\n## Security Checklist\n\n### 1. Secrets Management\n\n#### ❌ NEVER Do This\n```typescript\nconst apiKey = \"sk-proj-xxxxx\"  // Hardcoded secret\nconst dbPassword = \"password123\" // In source code\n```\n\n#### ✅ ALWAYS Do This\n```typescript\nconst apiKey = process.env.OPENAI_API_KEY\nconst dbUrl = process.env.DATABASE_URL\n\n// Verify secrets exist\nif (!apiKey) {\n  throw new Error('OPENAI_API_KEY not configured')\n}\n```\n\n#### Verification Steps\n- [ ] No hardcoded API keys, tokens, or passwords\n- [ ] All secrets in environment variables\n- [ ] `.env.local` in .gitignore\n- [ ] No secrets in git history\n- [ ] Production secrets in hosting platform (Vercel, Railway)\n\n### 2. Input Validation\n\n#### Always Validate User Input\n```typescript\nimport { z } from 'zod'\n\n// Define validation schema\nconst CreateUserSchema = z.object({\n  email: z.string().email(),\n  name: z.string().min(1).max(100),\n  age: z.number().int().min(0).max(150)\n})\n\n// Validate before processing\nexport async function createUser(input: unknown) {\n  try {\n    const validated = CreateUserSchema.parse(input)\n    return await db.users.create(validated)\n  } catch (error) {\n    if (error instanceof z.ZodError) {\n      return { success: false, errors: error.errors }\n    }\n    throw error\n  }\n}\n```\n\n#### File Upload Validation\n```typescript\nfunction validateFileUpload(file: File) {\n  // Size check (5MB max)\n  const maxSize = 5 * 1024 * 1024\n  if (file.size > maxSize) {\n    throw new Error('File too large (max 5MB)')\n  }\n\n  // Type check\n  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']\n  if (!allowedTypes.includes(file.type)) {\n    throw new Error('Invalid file type')\n  }\n\n  // Extension check\n  const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']\n  const extension = file.name.toLowerCase().match(/\\.[^.]+$/)?.[0]\n  if (!extension || !allowedExtensions.includes(extension)) {\n    throw new Error('Invalid file extension')\n  }\n\n  return true\n}\n```\n\n#### Verification Steps\n- [ ] All user inputs validated with schemas\n- [ ] File uploads restricted (size, type, extension)\n- [ ] No direct use of user input in queries\n- [ ] Whitelist validation (not blacklist)\n- [ ] Error messages don't leak sensitive info\n\n### 3. SQL Injection Prevention\n\n#### ❌ NEVER Concatenate SQL\n```typescript\n// DANGEROUS - SQL Injection vulnerability\nconst query = `SELECT * FROM users WHERE email = '${userEmail}'`\nawait db.query(query)\n```\n\n#### ✅ ALWAYS Use Parameterized Queries\n```typescript\n// Safe - parameterized query\nconst { data } = await supabase\n  .from('users')\n  .select('*')\n  .eq('email', userEmail)\n\n// Or with raw SQL\nawait db.query(\n  'SELECT * FROM users WHERE email = $1',\n  [userEmail]\n)\n```\n\n#### Verification Steps\n- [ ] All database queries use parameterized queries\n- [ ] No string concatenation in SQL\n- [ ] ORM/query builder used correctly\n- [ ] Supabase queries properly sanitized\n\n### 4. Authentication & Authorization\n\n#### JWT Token Handling\n```typescript\n// ❌ WRONG: localStorage (vulnerable to XSS)\nlocalStorage.setItem('token', token)\n\n// ✅ CORRECT: httpOnly cookies\nres.setHeader('Set-Cookie',\n  `token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)\n```\n\n#### Authorization Checks\n```typescript\nexport async function deleteUser(userId: string, requesterId: string) {\n  // ALWAYS verify authorization first\n  const requester = await db.users.findUnique({\n    where: { id: requesterId }\n  })\n\n  if (requester.role !== 'admin') {\n    return NextResponse.json(\n      { error: 'Unauthorized' },\n      { status: 403 }\n    )\n  }\n\n  // Proceed with deletion\n  await db.users.delete({ where: { id: userId } })\n}\n```\n\n#### Row Level Security (Supabase)\n```sql\n-- Enable RLS on all tables\nALTER TABLE users ENABLE ROW LEVEL SECURITY;\n\n-- Users can only view their own data\nCREATE POLICY \"Users view own data\"\n  ON users FOR SELECT\n  USING (auth.uid() = id);\n\n-- Users can only update their own data\nCREATE POLICY \"Users update own data\"\n  ON users FOR UPDATE\n  USING (auth.uid() = id);\n```\n\n#### Verification Steps\n- [ ] Tokens stored in httpOnly cookies (not localStorage)\n- [ ] Authorization checks before sensitive operations\n- [ ] Row Level Security enabled in Supabase\n- [ ] Role-based access control implemented\n- [ ] Session management secure\n\n### 5. XSS Prevention\n\n#### Sanitize HTML\n```typescript\nimport DOMPurify from 'isomorphic-dompurify'\n\n// ALWAYS sanitize user-provided HTML\nfunction renderUserContent(html: string) {\n  const clean = DOMPurify.sanitize(html, {\n    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],\n    ALLOWED_ATTR: []\n  })\n  return <div dangerouslySetInnerHTML={{ __html: clean }} />\n}\n```\n\n#### Content Security Policy\n```typescript\n// next.config.js\nconst securityHeaders = [\n  {\n    key: 'Content-Security-Policy',\n    value: `\n      default-src 'self';\n      script-src 'self' 'unsafe-eval' 'unsafe-inline';\n      style-src 'self' 'unsafe-inline';\n      img-src 'self' data: https:;\n      font-src 'self';\n      connect-src 'self' https://api.example.com;\n    `.replace(/\\s{2,}/g, ' ').trim()\n  }\n]\n```\n\n#### Verification Steps\n- [ ] User-provided HTML sanitized\n- [ ] CSP headers configured\n- [ ] No unvalidated dynamic content rendering\n- [ ] React's built-in XSS protection used\n\n### 6. CSRF Protection\n\n#### CSRF Tokens\n```typescript\nimport { csrf } from '@/lib/csrf'\n\nexport async function POST(request: Request) {\n  const token = request.headers.get('X-CSRF-Token')\n\n  if (!csrf.verify(token)) {\n    return NextResponse.json(\n      { error: 'Invalid CSRF token' },\n      { status: 403 }\n    )\n  }\n\n  // Process request\n}\n```\n\n#### SameSite Cookies\n```typescript\nres.setHeader('Set-Cookie',\n  `session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)\n```\n\n#### Verification Steps\n- [ ] CSRF tokens on state-changing operations\n- [ ] SameSite=Strict on all cookies\n- [ ] Double-submit cookie pattern implemented\n\n### 7. Rate Limiting\n\n#### API Rate Limiting\n```typescript\nimport rateLimit from 'express-rate-limit'\n\nconst limiter = rateLimit({\n  windowMs: 15 * 60 * 1000, // 15 minutes\n  max: 100, // 100 requests per window\n  message: 'Too many requests'\n})\n\n// Apply to routes\napp.use('/api/', limiter)\n```\n\n#### Expensive Operations\n```typescript\n// Aggressive rate limiting for searches\nconst searchLimiter = rateLimit({\n  windowMs: 60 * 1000, // 1 minute\n  max: 10, // 10 requests per minute\n  message: 'Too many search requests'\n})\n\napp.use('/api/search', searchLimiter)\n```\n\n#### Verification Steps\n- [ ] Rate limiting on all API endpoints\n- [ ] Stricter limits on expensive operations\n- [ ] IP-based rate limiting\n- [ ] User-based rate limiting (authenticated)\n\n### 8. Sensitive Data Exposure\n\n#### Logging\n```typescript\n// ❌ WRONG: Logging sensitive data\nconsole.log('User login:', { email, password })\nconsole.log('Payment:', { cardNumber, cvv })\n\n// ✅ CORRECT: Redact sensitive data\nconsole.log('User login:', { email, userId })\nconsole.log('Payment:', { last4: card.last4, userId })\n```\n\n#### Error Messages\n```typescript\n// ❌ WRONG: Exposing internal details\ncatch (error) {\n  return NextResponse.json(\n    { error: error.message, stack: error.stack },\n    { status: 500 }\n  )\n}\n\n// ✅ CORRECT: Generic error messages\ncatch (error) {\n  console.error('Internal error:', error)\n  return NextResponse.json(\n    { error: 'An error occurred. Please try again.' },\n    { status: 500 }\n  )\n}\n```\n\n#### Verification Steps\n- [ ] No passwords, tokens, or secrets in logs\n- [ ] Error messages generic for users\n- [ ] Detailed errors only in server logs\n- [ ] No stack traces exposed to users\n\n### 9. Blockchain Security (Solana)\n\n#### Wallet Verification\n```typescript\nimport { verify } from '@solana/web3.js'\n\nasync function verifyWalletOwnership(\n  publicKey: string,\n  signature: string,\n  message: string\n) {\n  try {\n    const isValid = verify(\n      Buffer.from(message),\n      Buffer.from(signature, 'base64'),\n      Buffer.from(publicKey, 'base64')\n    )\n    return isValid\n  } catch (error) {\n    return false\n  }\n}\n```\n\n#### Transaction Verification\n```typescript\nasync function verifyTransaction(transaction: Transaction) {\n  // Verify recipient\n  if (transaction.to !== expectedRecipient) {\n    throw new Error('Invalid recipient')\n  }\n\n  // Verify amount\n  if (transaction.amount > maxAmount) {\n    throw new Error('Amount exceeds limit')\n  }\n\n  // Verify user has sufficient balance\n  const balance = await getBalance(transaction.from)\n  if (balance < transaction.amount) {\n    throw new Error('Insufficient balance')\n  }\n\n  return true\n}\n```\n\n#### Verification Steps\n- [ ] Wallet signatures verified\n- [ ] Transaction details validated\n- [ ] Balance checks before transactions\n- [ ] No blind transaction signing\n\n### 10. Dependency Security\n\n#### Regular Updates\n```bash\n# Check for vulnerabilities\nnpm audit\n\n# Fix automatically fixable issues\nnpm audit fix\n\n# Update dependencies\nnpm update\n\n# Check for outdated packages\nnpm outdated\n```\n\n#### Lock Files\n```bash\n# ALWAYS commit lock files\ngit add package-lock.json\n\n# Use in CI/CD for reproducible builds\nnpm ci  # Instead of npm install\n```\n\n#### Verification Steps\n- [ ] Dependencies up to date\n- [ ] No known vulnerabilities (npm audit clean)\n- [ ] Lock files committed\n- [ ] Dependabot enabled on GitHub\n- [ ] Regular security updates\n\n## Security Testing\n\n### Automated Security Tests\n```typescript\n// Test authentication\ntest('requires authentication', async () => {\n  const response = await fetch('/api/protected')\n  expect(response.status).toBe(401)\n})\n\n// Test authorization\ntest('requires admin role', async () => {\n  const response = await fetch('/api/admin', {\n    headers: { Authorization: `Bearer ${userToken}` }\n  })\n  expect(response.status).toBe(403)\n})\n\n// Test input validation\ntest('rejects invalid input', async () => {\n  const response = await fetch('/api/users', {\n    method: 'POST',\n    body: JSON.stringify({ email: 'not-an-email' })\n  })\n  expect(response.status).toBe(400)\n})\n\n// Test rate limiting\ntest('enforces rate limits', async () => {\n  const requests = Array(101).fill(null).map(() =>\n    fetch('/api/endpoint')\n  )\n\n  const responses = await Promise.all(requests)\n  const tooManyRequests = responses.filter(r => r.status === 429)\n\n  expect(tooManyRequests.length).toBeGreaterThan(0)\n})\n```\n\n## Pre-Deployment Security Checklist\n\nBefore ANY production deployment:\n\n- [ ] **Secrets**: No hardcoded secrets, all in env vars\n- [ ] **Input Validation**: All user inputs validated\n- [ ] **SQL Injection**: All queries parameterized\n- [ ] **XSS**: User content sanitized\n- [ ] **CSRF**: Protection enabled\n- [ ] **Authentication**: Proper token handling\n- [ ] **Authorization**: Role checks in place\n- [ ] **Rate Limiting**: Enabled on all endpoints\n- [ ] **HTTPS**: Enforced in production\n- [ ] **Security Headers**: CSP, X-Frame-Options configured\n- [ ] **Error Handling**: No sensitive data in errors\n- [ ] **Logging**: No sensitive data logged\n- [ ] **Dependencies**: Up to date, no vulnerabilities\n- [ ] **Row Level Security**: Enabled in Supabase\n- [ ] **CORS**: Properly configured\n- [ ] **File Uploads**: Validated (size, type)\n- [ ] **Wallet Signatures**: Verified (if blockchain)\n\n## Resources\n\n- [OWASP Top 10](https://owasp.org/www-project-top-ten/)\n- [Next.js Security](https://nextjs.org/docs/security)\n- [Supabase Security](https://supabase.com/docs/guides/auth)\n- [Web Security Academy](https://portswigger.net/web-security)\n\n---\n\n**Remember**: Security is not optional. One vulnerability can compromise the entire platform. When in doubt, err on the side of caution.\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["skill","security","review","antigravity","awesome","skills","sickn33"],"capabilities":["skill","source-sickn33","category-antigravity-awesome-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/cc-skill-security-review","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under sickn33/antigravity-awesome-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-25T09:40:43.275Z","embedding":null,"createdAt":"2026-04-18T20:35:41.298Z","updatedAt":"2026-04-25T09:40:43.275Z","lastSeenAt":"2026-04-25T09:40:43.275Z","tsv":"'/api':762 '/api/admin':1122 '/api/endpoint':1173 '/api/protected':1106 '/api/search':792 '/api/users':1143 '/docs/guides/auth)':1304 '/docs/security)':1299 '/g':631 '/lib/csrf':665 '/web-security)':1310 '/www-project-top-ten/)':1294 '0':171,261,1188 '1':64,164,359,778 '10':781,782,1018,1291 '100':166,749,750 '1000':745,777 '101':1168 '1024':220,221 '15':743,746 '150':173 '2':140,630 '3':307 '3600':413 '4':382 '400':1156 '401':1110 '403':444,689,1130 '429':1184 '5':219,539 '500':867,888 '5mb':215,232 '6':656 '60':744,776 '7':725 '8':818 '9':915 'academi':1307 'access':533 'action':1344 'add':1054 'admin':438,1115 'age':167,412 'aggress':767 'allow':565,572 'allowedextens':252 'allowedextensions.includes':264 'allowedtyp':236 'allowedtypes.includes':241 'alter':463 'alway':85,143,330,425,551,1049 'amount':972,979 'antigrav':5 'api':42,61,92,107,115,728,800 'api.example.com':627 'apikey':72,90,102 'app.use':761,791 'appli':758 'applic':1338 'array':1167 'ask':1382 'async':178,418,667,926,956,1101,1117,1138,1164 'attr':573 'audit':1028,1034,1078 'auth.uid':488,508 'authent':31,383,817,1097,1100,1224 'author':33,384,414,427,519,1112,1124,1228 'autom':1092 'automat':1030 'await':189,327,340,352,431,448,989,1104,1120,1141,1176 'awesom':6 'b':567 'balanc':986,988,993,999,1010 'base':532,809,814 'base64':943,946 'bash':1023,1048 'bearer':1125 'best':21 'blacklist':299 'blind':1015 'blockchain':916,1287 'bodi':1146 'boundari':1390 'buffer.from':939,941,944 'build':1061 'builder':375 'built':651 'built-in':650 'card.last4':849 'cardnumb':835 'catch':192,858,872,949 'category-antigravity-awesome-skills' 'caution':1331 'cc':1 'chang':712 'check':214,234,250,415,520,1011,1024,1040,1230 'checklist':63,1193 'ci':1063 'ci/cd':1058 'clarif':1384 'clean':562,578,1079 'clear':1357 'code':18,84 'commit':1050,1082 'compromis':1319 'concaten':312,371 'configur':110,642,1250,1277 'connect':624 'connect-src':623 'console.error':874 'console.log':828,833,841,846 'const':71,79,89,94,155,184,217,235,251,257,319,338,429,561,584,672,739,772,936,987,1102,1118,1139,1165,1174,1179 'content':579,588,646,1219 'content-security-polici':587 'control':534 'cooki':399,403,516,693,698,718,722 'cor':1275 'correct':377,397,837,868 'creat':40,477,497 'createus':180 'createuserschema':156 'createuserschema.parse':186 'credenti':48 'criteria':1393 'csp':640,1245 'csrf':657,659,663,677,686,707,1221 'csrf.verify':680 'cvv':836 'danger':315 'dangerouslysetinnerhtml':576 'data':56,339,476,482,496,502,617,820,827,840,1255,1261 'databas':364 'date':1073,1266 'db.query':328,353 'db.users.create':190 'db.users.delete':449 'db.users.findunique':432 'dbpassword':80 'dburl':95 'default':593 'default-src':592 'defin':152 'delet':447 'deleteus':420 'depend':1019,1037,1070,1263 'dependabot':1083 'deploy':1191,1197 'describ':1345,1361 'detail':857,903,1008 'direct':289 'div':575 'dompurifi':546,550 'dompurify.sanitize':563 'doubl':720 'double-submit':719 'doubt':1325 'dynam':645 'em':569 'email':158,160,325,346,358,831,844,1148,1152 'enabl':458,466,527,1084,1223,1235,1272 'endpoint':43,801,1238 'enforc':1161,1240 'ensur':16 'entir':1321 'env':1204 'env.local':125 'environ':123,1373 'environment-specif':1372 'eq':345 'err':1326 'error':105,193,195,201,204,227,245,268,300,441,684,851,859,862,870,873,876,877,880,882,898,904,950,968,978,997,1251,1257 'error.errors':202 'error.message':863 'error.stack':865 'eval':602 'exceed':980 'execut':1340 'exist':100 'expect':1107,1127,1153,1185 'expectedrecipi':965 'expens':764,805 'expert':1378 'export':177,417,666 'expos':855,912 'exposur':821 'express':736 'express-rate-limit':735 'extens':249,258,263,265,271,287 'fals':200,952 'featur':51 'fetch':1105,1121,1142,1172 'file':38,205,211,212,228,247,270,282,1047,1052,1081,1278 'file.name.tolowercase':259 'file.size':223 'file.type':242 'fill':1169 'first':428 'fix':1029,1035 'fixabl':1031 'follow':19 'font':620 'font-src':619 'frame':1248 'function':179,209,419,557,668,927,957 'generic':869,900 'getbal':990 'gif':256 'git':131,1053 'github':1086 'gitignor':127 'handl':34,387,1227,1252 'hardcod':77,114,1200 'header':641,1123,1244 'histori':132 'host':136 'html':543,556,559,564,577,638 'httpon':398,406,515,701 'https':618,1239 'id':434,451,489,509 'identifi':24 'image/gif':239 'image/jpeg':237 'image/png':238 'img':614 'img-src':613 'implement':30,49,535,724 'import':148,545,662,732,922 'info':306 'inject':309,317,1213 'inlin':605,612 'input':36,141,146,181,187,278,293,1132,1137,1206,1210,1387 'instal':1067 'instanceof':196 'instead':1064 'insuffici':998 'int':169 'integr':57 'intern':856,875 'invalid':246,269,685,969,1136 'ip':808 'ip-bas':807 'isomorph':549 'isomorphic-dompurifi':548 'issu':1032 'isvalid':937,948 'jpeg':254 'jpg':253 'json.stringify':1147 'jwt':385 'key':93,108,116,586 'known':1075 'larg':230 'last4':848 'leak':304 'level':454,468,525,1270 'limit':727,730,738,740,763,769,797,803,811,816,981,1159,1163,1234,1349 'localstorag':390,518 'localstorage.setitem':394 'lock':1046,1051,1080 'log':822,825,897,908,1258,1262 'login':830,843 'manag':66,537 'mani':756,788 'map':1171 'match':260,1358 'max':165,172,216,231,411,748,780 'max-ag':410 'maxamount':975 'maxsiz':218,224 'messag':301,754,786,852,871,899,933,940 'method':1144 'min':163,170 'minut':747,779,785 'miss':1395 'name':161 'never':67,311 'new':41,104,226,244,267,967,977,996 'next.config.js':583 'next.js':1295 'nextjs.org':1298 'nextjs.org/docs/security)':1297 'nextresponse.json':440,683,861,879 'not-an-email':1149 'npm':1027,1033,1038,1044,1062,1066,1077 'null':1170 'occur':883 'one':1316 'openai':106 'oper':523,713,765,806 'option':1249,1315 'orm/query':374 'outdat':1042,1045 'output':1367 'overview':1348 'owasp':1289 'owasp.org':1293 'owasp.org/www-project-top-ten/)':1292 'p':571 'packag':1043 'package-lock.json':1055 'parameter':332,336,367,1216 'parti':60 'password':119,832,892 'password123':81 'pattern':723 'payment':50,834,847 'per':752,784 'permiss':1388 'place':1232 'platform':137,1322 'pleas':884 'png':255 'polici':478,498,581,590 'portswigger.net':1309 'portswigger.net/web-security)':1308 'post':669,1145 'potenti':25 'practic':22 'pre':1190 'pre-deploy':1189 'prevent':310,541 'proceed':445 'process':176,690 'process.env.database':96 'process.env.openai':91 'product':133,1196,1242 'proj':75 'promise.all':1177 'proper':380,1225,1276 'protect':654,658,1222 'provid':555,637 'publickey':929,945 'queri':295,320,329,333,337,365,368,379,1215 'r':1182 'r.status':1183 'railway':139 'rate':726,729,737,768,796,810,815,1158,1162,1233 'ratelimit':733,741,774 'raw':350 'react':648 'recipi':962,970 'redact':838 'regular':1021,1087 'reject':1135 'rememb':1311 'render':647 'renderusercont':558 'replac':628 'reproduc':1060 'request':430,670,671,691,751,757,783,790,1166,1178 'request.headers.get':674 'requester.role':437 'requesterid':423,435 'requir':1099,1114,1386 'res.setheader':400,695 'resourc':1288 'respons':1103,1119,1140,1175 'response.status':1108,1128,1154 'responses.filter':1181 'restrict':284 'return':188,198,272,439,574,682,860,878,947,951,1000 'review':4,12,1379 'rls':459 'role':531,1116,1229 'role-bas':530 'rout':760 'row':453,467,524,1269 'safe':335 'safeti':1389 'samesit':408,692,703,714 'sanit':381,542,552,639,1220 'schema':154,281 'scope':1360 'script':597 'script-src':596 'search':771,789 'searchlimit':773,793 'secret':46,65,78,99,121,129,134,895,1198,1201 'secur':3,11,20,62,407,455,469,526,538,580,589,702,917,1020,1088,1090,1093,1192,1243,1271,1296,1301,1306,1312 'securityhead':585 'select':321,344,354,486 'self':595,599,609,616,622,626 'sensit':55,305,522,819,826,839,1254,1260 'server':907 'session':536,699 'sessionid':700 'set':402,697 'set-cooki':401,696 'sickn33':10 'side':1329 'sign':1017 'signatur':931,942,1005,1284 'size':213,285,1281 'sk':74 'sk-proj-xxxxx':73 'skill':2,7,8,13,15,1336,1352 'solana':918 'solana/web3.js':925 'sourc':83 'source-sickn33' 'specif':1374 'sql':308,313,316,351,373,457,1212 'src':594,598,608,615,621,625 'stack':864,910 'state':711 'state-chang':710 'status':443,688,866,887 'step':112,275,362,511,634,706,795,890,1003,1069 'stop':1380 'store':52,513 'strict':409,704,715 'stricter':802 'string':370,422,424,560,930,932,934 'strong':570 'style':607 'style-src':606 'submit':721 'substitut':1370 'success':199,1392 'suffici':985 'supabas':341,378,456,529,1274,1300 'supabase.com':1303 'supabase.com/docs/guides/auth)':1302 'tabl':462,464 'tag':566 'task':1356 'test':1091,1094,1096,1098,1111,1113,1131,1134,1157,1160,1376 'third':59 'third-parti':58 'throw':103,203,225,243,266,966,976,995 'tobe':1109,1129,1155 'tobegreaterthan':1187 'token':117,386,395,396,404,405,512,660,673,678,681,687,708,893,1226 'toomanyrequest':1180 'toomanyrequests.length':1186 'top':1290 'trace':911 'transact':953,959,960,1007,1013,1016 'transaction.amount':974,994 'transaction.from':991 'transaction.to':964 'transmit':54 'treat':1365 'tri':183,885,935 'trim':632 'true':273,1001 'type':233,248,286,1282 'typescript':70,88,147,208,314,334,388,416,544,582,661,694,731,766,823,853,921,955,1095 'unauthor':442 'unknown':182 'unsaf':601,604,611 'unsafe-ev':600 'unsafe-inlin':603,610 'unvalid':644 'updat':493,500,506,1022,1036,1039,1089 'upload':39,206,283,1279 'url':97 'use':29,290,331,366,376,487,507,655,1056,1334,1350 'user':35,145,277,292,323,343,356,465,470,479,484,490,499,504,554,636,813,829,842,902,914,983,1209,1218 'user-bas':812 'user-provid':553,635 'useremail':326,347,360 'userid':421,452,845,850 'usertoken':1126 'valid':142,144,153,174,185,191,207,279,297,1009,1133,1207,1211,1280,1375 'validatefileupload':210 'valu':591 'var':1205 'variabl':124 'vercel':138 'verif':111,274,361,510,633,705,794,889,920,954,1002,1068 'verifi':98,426,923,938,961,971,982,1006,1285 'verifytransact':958 'verifywalletownership':928 'view':473,480 'vulner':26,318,391,1026,1076,1268,1317 'wallet':919,1004,1283 'web':1305 'whitelist':296 'window':753 'windowm':742,775 'work':44 'workflow':1342 'wrong':389,824,854 'x':676,1247 'x-csrf-token':675 'x-frame-opt':1246 'xss':393,540,653,1217 'xxxxx':76 'z':149 'z.number':168 'z.object':157 'z.string':159,162 'z.zoderror':197 'zod':151","prices":[{"id":"3e4726de-eef8-4e17-bf7b-a904bb22ebf3","listingId":"3e3f45bd-ba8e-4b6a-b1fb-591eac123fc0","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:35:41.298Z"}],"sources":[{"listingId":"3e3f45bd-ba8e-4b6a-b1fb-591eac123fc0","source":"github","sourceId":"sickn33/antigravity-awesome-skills/cc-skill-security-review","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/cc-skill-security-review","isPrimary":false,"firstSeenAt":"2026-04-18T21:34:07.149Z","lastSeenAt":"2026-04-25T06:50:47.419Z"},{"listingId":"3e3f45bd-ba8e-4b6a-b1fb-591eac123fc0","source":"skills_sh","sourceId":"sickn33/antigravity-awesome-skills/cc-skill-security-review","sourceUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/cc-skill-security-review","isPrimary":true,"firstSeenAt":"2026-04-18T20:35:41.298Z","lastSeenAt":"2026-04-25T09:40:43.275Z"}],"details":{"listingId":"3e3f45bd-ba8e-4b6a-b1fb-591eac123fc0","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"cc-skill-security-review","source":"skills_sh","category":"antigravity-awesome-skills","skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/cc-skill-security-review"},"updatedAt":"2026-04-25T09:40:43.275Z"}}