secanix 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -1,42 +1,42 @@
1
- # Secanix
2
-
3
- Security scanner buat app hasil vibe-coding (Next.js + Supabase/Firebase).
4
-
5
- Checks it runs:
6
- - Leaked secrets (API keys, tokens, credentials committed to the repo)
7
- - Exposed Supabase service role keys
8
- - Missing auth on Next.js API routes
9
- - Disabled Supabase Row Level Security (RLS)
10
- - CORS wildcard origins
11
- - Vulnerable dependencies (known CVEs)
12
-
13
- ## CLI Usage
14
-
15
- ```
16
- npx -p secanix@latest secanix
17
- ```
18
- Runs all checks against the current directory and prints a human-readable report.
19
-
20
- ```
21
- npx -p secanix@latest secanix --json
22
- ```
23
- Same scan, machine-readable JSON output — useful for piping into other tooling.
24
-
25
- ## GitHub Action
26
-
27
- Add to `.github/workflows/security-scan.yml` in your repo:
28
-
29
- ```yaml
30
- name: Security Scan
31
- on: pull_request
32
- permissions:
33
- pull-requests: write
34
- jobs:
35
- scan:
36
- runs-on: ubuntu-latest
37
- steps:
38
- - uses: actions/checkout@v4
39
- - uses: cutryandifonna/secanix@v1
40
- ```
41
-
42
- The action fails CI when a critical finding is present (leaked secret, exposed Supabase service role key, or RLS disabled). It posts and updates a single PR comment listing all findings by severity. This requires the consuming workflow to grant `permissions: pull-requests: write` itself, as shown above — without it, comment posting fails with a 403. GitHub-hosted `ubuntu-latest` runners (uses `sudo` for tool installs — self-hosted runners need equivalent permissions).
1
+ # Secanix
2
+
3
+ Security scanner buat app hasil vibe-coding (Next.js + Supabase/Firebase).
4
+
5
+ Checks it runs:
6
+ - Leaked secrets (API keys, tokens, credentials committed to the repo)
7
+ - Exposed Supabase service role keys
8
+ - Missing auth on Next.js API routes
9
+ - Disabled Supabase Row Level Security (RLS)
10
+ - CORS wildcard origins
11
+ - Vulnerable dependencies (known CVEs)
12
+
13
+ ## CLI Usage
14
+
15
+ ```
16
+ npx -p secanix@latest secanix
17
+ ```
18
+ Runs all checks against the current directory and prints a human-readable report.
19
+
20
+ ```
21
+ npx -p secanix@latest secanix --json
22
+ ```
23
+ Same scan, machine-readable JSON output — useful for piping into other tooling.
24
+
25
+ ## GitHub Action
26
+
27
+ Add to `.github/workflows/security-scan.yml` in your repo:
28
+
29
+ ```yaml
30
+ name: Security Scan
31
+ on: pull_request
32
+ permissions:
33
+ pull-requests: write
34
+ jobs:
35
+ scan:
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - uses: cutryandifonna/secanix@v1
40
+ ```
41
+
42
+ The action fails CI when a critical finding is present (leaked secret, exposed Supabase service role key, or RLS disabled). It posts and updates a single PR comment listing all findings by severity. This requires the consuming workflow to grant `permissions: pull-requests: write` itself, as shown above — without it, comment posting fails with a 403. GitHub-hosted `ubuntu-latest` runners (uses `sudo` for tool installs — self-hosted runners need equivalent permissions).
@@ -69,7 +69,6 @@ export async function findMissingApiAuth(targetDir) {
69
69
  RULE_PATH,
70
70
  "--json",
71
71
  "--quiet",
72
- "--no-git-ignore",
73
72
  targetDir,
74
73
  ]);
75
74
  return parseSemgrepReport(stdout).map((finding) => ({
@@ -1,7 +1,10 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { dirname, join } from "node:path";
2
3
  import { mkdtemp, readFile, rm } from "node:fs/promises";
3
4
  import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const CONFIG_PATH = join(__dirname, "..", "rules", "gitleaks-config.toml");
5
8
  export class GitleaksNotFoundError extends Error {
6
9
  constructor() {
7
10
  super("gitleaks gak ketemu di PATH. Install: https://github.com/gitleaks/gitleaks#installing");
@@ -68,6 +71,8 @@ export async function runSecretScan(targetDir) {
68
71
  targetDir,
69
72
  "--no-git",
70
73
  "--no-banner",
74
+ "--config",
75
+ CONFIG_PATH,
71
76
  "--report-format",
72
77
  "json",
73
78
  "--report-path",
@@ -0,0 +1,13 @@
1
+ [extend]
2
+ useDefault = true
3
+
4
+ [allowlist]
5
+ paths = [
6
+ '''(^|/)node_modules(/|$)''',
7
+ '''(^|/)\.git(/|$)''',
8
+ '''(^|/)\.next(/|$)''',
9
+ '''(^|/)dist(/|$)''',
10
+ '''(^|/)build(/|$)''',
11
+ '''(^|/)out(/|$)''',
12
+ '''(^|/)coverage(/|$)''',
13
+ ]
@@ -1,24 +1,24 @@
1
- rules:
2
- - id: nextjs-api-route-missing-auth
3
- languages: [typescript, javascript]
4
- severity: WARNING
5
- message: >-
6
- API route Next.js ini kelihatan gak ada auth check (session/token) sebelum jalanin logic.
7
- paths:
8
- include:
9
- - "pages/api/**"
10
- - "src/pages/api/**"
11
- - "app/**/route.ts"
12
- - "app/**/route.js"
13
- - "src/app/**/route.ts"
14
- - "src/app/**/route.js"
15
- patterns:
16
- - pattern-either:
17
- - pattern: export default function $HANDLER(...) { ... }
18
- - pattern: export default async function $HANDLER(...) { ... }
19
- - pattern: export async function GET(...) { ... }
20
- - pattern: export async function POST(...) { ... }
21
- - pattern: export async function PUT(...) { ... }
22
- - pattern: export async function PATCH(...) { ... }
23
- - pattern: export async function DELETE(...) { ... }
24
- - pattern-not-regex: (?i)(getServerSession|getToken|currentUser|verifyAuth|requireAuth|withAuth|auth\(\)|\.auth\.getUser|\.auth\.getSession|jwt\.verify|isAuthenticated|checkAuth)
1
+ rules:
2
+ - id: nextjs-api-route-missing-auth
3
+ languages: [typescript, javascript]
4
+ severity: WARNING
5
+ message: >-
6
+ API route Next.js ini kelihatan gak ada auth check (session/token) sebelum jalanin logic.
7
+ paths:
8
+ include:
9
+ - "pages/api/**"
10
+ - "src/pages/api/**"
11
+ - "app/**/route.ts"
12
+ - "app/**/route.js"
13
+ - "src/app/**/route.ts"
14
+ - "src/app/**/route.js"
15
+ patterns:
16
+ - pattern-either:
17
+ - pattern: export default function $HANDLER(...) { ... }
18
+ - pattern: export default async function $HANDLER(...) { ... }
19
+ - pattern: export async function GET(...) { ... }
20
+ - pattern: export async function POST(...) { ... }
21
+ - pattern: export async function PUT(...) { ... }
22
+ - pattern: export async function PATCH(...) { ... }
23
+ - pattern: export async function DELETE(...) { ... }
24
+ - pattern-not-regex: (?i)(getServerSession|getToken|currentUser|verifyAuth|requireAuth|withAuth|auth\(\)|\.auth\.getUser|\.auth\.getSession|jwt\.verify|isAuthenticated|checkAuth)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secanix",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "description": "Security scanner buat app hasil vibe-coding (Next.js + Supabase/Firebase).",
6
6
  "license": "MIT",