@justmpm/firebase-audit 0.5.15 → 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-ZILSDI3F.js → chunk-5KZCV2CB.js} +1 -1
- package/dist/{chunk-SYGLJ457.js → chunk-NZPB7V2V.js} +14 -3
- 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-3XBJMCAO.js → scan-MG76BJPM.js} +1 -1
- package/package.json +1 -1
|
@@ -224,8 +224,18 @@ function make(rule, severity, confidence, message, fingerprint, opts = {}) {
|
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
226
|
function checksAdminPower(cond, condRaw, rule, helperDetailed) {
|
|
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);
|
|
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) {
|
|
@@ -248,7 +258,7 @@ function checksAdminPower(cond, condRaw, rule, helperDetailed) {
|
|
|
248
258
|
const p = part;
|
|
249
259
|
return /token\.admin\b/i.test(p) || /token\.get\(\s*['"]admin['"]/i.test(p) || /token\s*\[\s*['"]admin['"]/i.test(p) || /token\.\w+\s*==\s*['"]admin['"]/i.test(p) || /token\.\w+\s+in\s+[^\n;]*['"]admin['"]/i.test(p);
|
|
250
260
|
}) : true;
|
|
251
|
-
const checksAdminRole = !isInvertedAdmin && hasTopOr ? adminPerDisjunct : /token\.\w+\s*==\s*['"]admin['"]/i.test(cond) || /token\s*\[\s*['"]\w+['"]\s*\]\s*==\s*['"]admin['"]/i.test(cond) || /token\.\w+\s+in\s+[^\n;]*['"]admin['"]/i.test(cond) || /token\.get\(\s*['"]admin['"]/i.test(cond) || isAdminBodyHasAdmin;
|
|
261
|
+
const checksAdminRole = !isInvertedAdmin && (hasTopOr ? adminPerDisjunct : /token\.\w+\s*==\s*['"]admin['"]/i.test(cond) || /token\s*\[\s*['"]\w+['"]\s*\]\s*==\s*['"]admin['"]/i.test(cond) || /token\.\w+\s+in\s+[^\n;]*['"]admin['"]/i.test(cond) || /token\.get\(\s*['"]admin['"]/i.test(cond) || isAdminBodyHasAdmin);
|
|
252
262
|
if (checksAdminClaim || checksAdminRole) {
|
|
253
263
|
if (hasTopOr && !adminPerDisjunct) return false;
|
|
254
264
|
return true;
|
|
@@ -260,6 +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) {
|
|
273
|
+
if (/![\s(]*(?:firestore\.)?$/.test(branch.slice(0, m.index))) continue;
|
|
263
274
|
let depth = 0;
|
|
264
275
|
const start = m.index + m[0].length;
|
|
265
276
|
let end = -1;
|
|
@@ -566,7 +577,7 @@ async function runChecks(model, rootDir, opts = {}) {
|
|
|
566
577
|
for (const rule of model.rules) {
|
|
567
578
|
const segments = rule.path.split("/").filter((s) => s.length > 0).map((s) => s.toLowerCase());
|
|
568
579
|
const adminIdx = segments.indexOf("admins");
|
|
569
|
-
if (adminIdx === -1 || adminIdx +
|
|
580
|
+
if (adminIdx === -1 || adminIdx + 2 !== segments.length) continue;
|
|
570
581
|
const ruleOps = new Set(rule.operations.flatMap(expandOp));
|
|
571
582
|
const escalating = ["create", "write", "update"].filter((o) => ruleOps.has(o));
|
|
572
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",
|