@justmpm/firebase-audit 0.5.16 → 0.5.17
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/dist/{chunk-PVB6GT4F.js → chunk-5KZCV2CB.js} +1 -1
- package/dist/{chunk-DXYPKVMR.js → chunk-NZPB7V2V.js} +12 -2
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/mcp-cli.js +2 -2
- package/dist/mcp.js +2 -2
- package/dist/{scan-6HV5HFKH.js → scan-MG76BJPM.js} +1 -1
- package/package.json +1 -1
|
@@ -226,6 +226,16 @@ function make(rule, severity, confidence, message, fingerprint, opts = {}) {
|
|
|
226
226
|
function checksAdminPower(cond, condRaw, rule, helperDetailed) {
|
|
227
227
|
const isInvertedAdmin = /admin\s*==\s*false/i.test(cond) || /admin\s*!=\s*true/i.test(cond) || /admin\s*!==\s*true/i.test(cond) || /!\s*request\.auth\.token\.admin\b/i.test(cond) || /!\s*\(\s*request\.auth\.token\.admin\b/i.test(cond) || /!\s*\([^()]*admin\s*==\s*true/i.test(cond) || /!\s*\([^()]*==\s*['"]admin['"]/i.test(cond);
|
|
228
228
|
const normClaim = (c) => c.toLowerCase().replace(/[_-]/g, "");
|
|
229
|
+
for (const target of [condRaw, cond]) {
|
|
230
|
+
const negCall = /!\s*\(?\s*((?:[A-Za-z_][A-Za-z0-9_]*\.)*[A-Za-z_][A-Za-z0-9_]*)\s*\(/.exec(target) ?? /((?:[A-Za-z_][A-Za-z0-9_]*\.)*[A-Za-z_][A-Za-z0-9_]*)\s*\([^()]*\)\s*(==\s*false|!=\s*true|!==\s*true)/.exec(target);
|
|
231
|
+
if (!negCall) continue;
|
|
232
|
+
const dotted = negCall[1];
|
|
233
|
+
const simple = dotted.split(".").pop();
|
|
234
|
+
const fn = helperDetailed.get(simple) ?? helperDetailed.get(simple.toLowerCase());
|
|
235
|
+
const body = fn ? fn.body : "";
|
|
236
|
+
const bodyHasAdmin = /token\.admin\b/i.test(body) || /token\.get\(\s*['"]admin['"]/i.test(body) || /==\s*['"]admin['"]/i.test(body) || /request\.auth\.token/i.test(body);
|
|
237
|
+
if (bodyHasAdmin || /^request\.auth\.token\b/i.test(dotted)) return false;
|
|
238
|
+
}
|
|
229
239
|
const isAdminCall = /\bisadmin\s*\(([^)]*)\)/i.exec(condRaw) ?? /\bisadmin\s*\(([^)]*)\)/i.exec(cond);
|
|
230
240
|
let isAdminBodyHasAdmin = false;
|
|
231
241
|
if (isAdminCall) {
|
|
@@ -260,7 +270,7 @@ function branchHasCallerDocGate(branch) {
|
|
|
260
270
|
const re = /\b(?:exists|get)\s*\(/gi;
|
|
261
271
|
let m;
|
|
262
272
|
while ((m = re.exec(branch)) !== null) {
|
|
263
|
-
if (
|
|
273
|
+
if (/![\s(]*(?:firestore\.)?$/.test(branch.slice(0, m.index))) continue;
|
|
264
274
|
let depth = 0;
|
|
265
275
|
const start = m.index + m[0].length;
|
|
266
276
|
let end = -1;
|
|
@@ -567,7 +577,7 @@ async function runChecks(model, rootDir, opts = {}) {
|
|
|
567
577
|
for (const rule of model.rules) {
|
|
568
578
|
const segments = rule.path.split("/").filter((s) => s.length > 0).map((s) => s.toLowerCase());
|
|
569
579
|
const adminIdx = segments.indexOf("admins");
|
|
570
|
-
if (adminIdx === -1 || adminIdx +
|
|
580
|
+
if (adminIdx === -1 || adminIdx + 2 !== segments.length) continue;
|
|
571
581
|
const ruleOps = new Set(rule.operations.flatMap(expandOp));
|
|
572
582
|
const escalating = ["create", "write", "update"].filter((o) => ruleOps.has(o));
|
|
573
583
|
if (escalating.length === 0) continue;
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
scan
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NZPB7V2V.js";
|
|
5
5
|
import "./chunk-7J3ADEBW.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -84,7 +84,7 @@ Uso: firebase-audit scan|check|verify|drift [--json] ...`);
|
|
|
84
84
|
const { resolve: resolveRoot } = await import("path");
|
|
85
85
|
const rootDir = cwdArg ? resolveRoot(process.cwd(), cwdArg) : process.cwd();
|
|
86
86
|
if (cmd === "verify") {
|
|
87
|
-
const { scan: scanForVerify } = await import("./scan-
|
|
87
|
+
const { scan: scanForVerify } = await import("./scan-MG76BJPM.js");
|
|
88
88
|
const { verify } = await import("./verify-GQSR4FQL.js");
|
|
89
89
|
const { resolve: resolveVerify } = await import("path");
|
|
90
90
|
const coverageArg = getArg("coverage");
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpServer,
|
|
3
3
|
startMcpServer
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5KZCV2CB.js";
|
|
5
5
|
import {
|
|
6
6
|
AccessOriginSchema,
|
|
7
7
|
AuditYamlSchema,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
runChecks,
|
|
35
35
|
scan,
|
|
36
36
|
validateClaimSamples
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-NZPB7V2V.js";
|
|
38
38
|
import {
|
|
39
39
|
buildFullPath,
|
|
40
40
|
conditionKeyForFingerprint,
|
package/dist/mcp-cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startMcpServer
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-5KZCV2CB.js";
|
|
5
|
+
import "./chunk-NZPB7V2V.js";
|
|
6
6
|
import "./chunk-7J3ADEBW.js";
|
|
7
7
|
import "./chunk-CSMT4PIP.js";
|
|
8
8
|
import "./chunk-LD3F73XI.js";
|
package/dist/mcp.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpServer,
|
|
3
3
|
startMcpServer
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-5KZCV2CB.js";
|
|
5
|
+
import "./chunk-NZPB7V2V.js";
|
|
6
6
|
import "./chunk-7J3ADEBW.js";
|
|
7
7
|
import "./chunk-CSMT4PIP.js";
|
|
8
8
|
import "./chunk-LD3F73XI.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justmpm/firebase-audit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.17",
|
|
4
4
|
"description": "Auditor de consistência e segurança para projetos Firebase: código + Rules + índices + contrato vs comportamento. Static-first, nunca inventa certeza.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"firebase",
|