@jikida/init 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/init.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * Everything is idempotent: re-running skips already-done steps.
13
13
  */
14
14
 
15
- import { readFileSync, existsSync, writeFileSync, appendFileSync, mkdirSync } from 'node:fs';
15
+ import { readFileSync, existsSync, writeFileSync, appendFileSync, mkdirSync, readdirSync } from 'node:fs';
16
16
  import { join, dirname } from 'node:path';
17
17
  import { fileURLToPath } from 'node:url';
18
18
  import { execSync, spawnSync } from 'node:child_process';
@@ -157,6 +157,20 @@ function installSkill() {
157
157
  warn(`Could not write ${rel}: ${e.message}`);
158
158
  }
159
159
  }
160
+ // Copy the bundled checklists (pre-deploy, supabase/firebase) next to the
161
+ // master skill so the assistant can walk them before a launch.
162
+ try {
163
+ const clSrc = join(here, '..', 'skill', 'checklists');
164
+ if (existsSync(clSrc)) {
165
+ const dstDir = join(cwd, '.claude', 'skills', 'jikida', 'checklists');
166
+ mkdirSync(dstDir, { recursive: true });
167
+ for (const f of readdirSync(clSrc)) {
168
+ writeFileSync(join(dstDir, f), readFileSync(join(clSrc, f), 'utf8'));
169
+ }
170
+ done('.claude/skills/jikida/checklists/'); wrote++;
171
+ }
172
+ } catch (e) { warn(`Could not copy checklists: ${e.message}`); }
173
+
160
174
  if (wrote > 0 || skipped > 0) {
161
175
  log('');
162
176
  if (skipped > 0) { log(` ${skipped} file(s) already had the skill — left untouched.`); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jikida/init",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "One command to install a production Web Application Firewall. Detects Node (Next.js / Express / Fastify), PHP (Laravel / Symfony), and Python (Django / FastAPI / Flask), installs the right Jikida SDK, wires the middleware, writes JIKIDA_TOKEN to .env. $0 to start. Fails open. Playground + MCP for Claude Code / Cursor / Windsurf included.",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -359,3 +359,10 @@ Default to the lowest level that fixes the finding. Anything destructive or irre
359
359
 
360
360
  - **Score** — start at 100; subtract Critical 20 / High 10 / Medium 5 / Low 2, floored at 0. Grade: 90+ A, 70+ B, 50+ C, below 50 F. Non-applicable categories drop out and their weight redistributes.
361
361
  - **Memory** — persist the score, accepted risks and custom rules across scans (in the app, or a local `memory-security.md` for the CLI). Re-runs show the trend and never re-flag an accepted risk. User preferences always win over a generic recommendation.
362
+
363
+ ## Checklists
364
+
365
+ Concrete runbooks bundled with this skill — walk them before a launch:
366
+
367
+ - `checklists/pre-deploy.md` — the full pre-ship checklist across every category.
368
+ - `checklists/supabase-firebase.md` — the #1 vibe-coder leak (open RLS / test-mode rules); check before any launch.
@@ -0,0 +1,46 @@
1
+ # Pre-deploy security checklist
2
+
3
+ Run this before every ship, merge, or "make the repo public". Each item maps to a Jikida check you can run with `npx @jikida/scan` or the MCP tools. Fix at the lowest safe level; ask before anything destructive.
4
+
5
+ ## Secrets
6
+ - [ ] No API keys, tokens, or passwords committed (grep the diff; run a repo scan).
7
+ - [ ] `.env`, `serviceAccountKey.json`, `*.pem`, `*.db` are in `.gitignore` and NOT tracked.
8
+ - [ ] No `service_role`, admin, or private key used in client-side code or shipped in the bundle.
9
+ - [ ] Rotate anything that was ever committed — removing it from HEAD is not enough.
10
+
11
+ ## Database
12
+ - [ ] Supabase RLS is ON for every table holding user data (default-deny, then explicit policies).
13
+ - [ ] Firebase rules are not `allow read, write: if true` (test mode).
14
+ - [ ] No endpoint trusts a client-supplied `userId` / `ownerId` (IDOR — scope by the session).
15
+ - [ ] PII columns are encrypted or access-controlled.
16
+
17
+ ## Auth & sessions
18
+ - [ ] Session cookies are `HttpOnly`, `Secure`, `SameSite`.
19
+ - [ ] Login and password-reset have brute-force limits.
20
+ - [ ] JWTs verify the signature and reject `alg=none`; tokens have an expiry.
21
+
22
+ ## Transport & headers
23
+ - [ ] HTTPS only; HSTS set.
24
+ - [ ] CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy present.
25
+ - [ ] CORS is an explicit origin allowlist — never `*` with credentials.
26
+
27
+ ## Input & injection
28
+ - [ ] All queries are parameterized (no string-built SQL / NoSQL).
29
+ - [ ] File uploads check real type (magic bytes), size, and a safe path.
30
+ - [ ] User input rendered in HTML is escaped; no `dangerouslySetInnerHTML` on untrusted data.
31
+
32
+ ## Dependencies & config
33
+ - [ ] No dependency with a known CVE (run the supply-chain check).
34
+ - [ ] Lockfile committed and up to date.
35
+ - [ ] Debug mode / verbose errors OFF in production.
36
+ - [ ] Rate limiting on auth, write, and expensive endpoints.
37
+
38
+ ## After deploy
39
+ - [ ] Uptime monitor + SSL/domain-expiry watch enabled on the live URL.
40
+ - [ ] A surface pentest run against the deployed site comes back clean or triaged.
41
+
42
+ Run it all at once:
43
+
44
+ ```
45
+ $ npx @jikida/scan yourdomain.com --repo . --min-score 80
46
+ ```
@@ -0,0 +1,38 @@
1
+ # Supabase & Firebase checklist
2
+
3
+ The single most common way an AI-built app leaks its whole database. Check this before any launch.
4
+
5
+ ## Supabase
6
+ - [ ] **RLS is enabled on every table with user data.** A table with RLS off is world-readable through the anon key.
7
+ ```sql
8
+ -- 🔴 CRITICAL — RLS off: anyone with the public anon key reads every row
9
+ -- 🟢 CORRECT — enable RLS, then add explicit policies
10
+ ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
11
+ CREATE POLICY "own rows" ON public.profiles
12
+ FOR SELECT USING (auth.uid() = user_id);
13
+ ```
14
+ - [ ] Policies are default-deny — a table with RLS on but no policy returns nothing, which is safe; a permissive `USING (true)` policy is not.
15
+ - [ ] The `service_role` key is used ONLY on the server, never in client code or the bundle.
16
+ - [ ] Storage buckets holding private files are not public.
17
+ - [ ] Postgres functions marked `SECURITY DEFINER` are reviewed — they bypass RLS.
18
+
19
+ ## Firebase
20
+ - [ ] Firestore/RTDB rules are not left in test mode.
21
+ ```
22
+ // 🔴 CRITICAL — test mode: the whole database is public read/write
23
+ match /{document=**} { allow read, write: if true; }
24
+ // 🟢 CORRECT — require auth and scope to the owner
25
+ match /users/{uid}/{doc=**} {
26
+ allow read, write: if request.auth != null && request.auth.uid == uid;
27
+ }
28
+ ```
29
+ - [ ] `google-services.json` / `serviceAccountKey.json` is not committed.
30
+ - [ ] Client API keys are restricted (referrer / bundle-id / API restrictions in the Google console) — a client key is public, so the rules are the real gate.
31
+ - [ ] Cloud Functions validate `context.auth` before any privileged action.
32
+ - [ ] Storage rules mirror the database rules — a locked DB with an open bucket still leaks.
33
+
34
+ Run the automated version:
35
+
36
+ ```
37
+ $ npx @jikida/scan --repo . # flags open RLS/rules, committed keys, service_role in client
38
+ ```