@vibedrift/cli 0.4.3 → 0.4.4

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/index.js CHANGED
@@ -2735,10 +2735,13 @@ var importsAnalyzer = {
2735
2735
  );
2736
2736
  const esmFiles = [];
2737
2737
  const cjsFiles = [];
2738
+ const SKIP_PATH = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\]/i;
2738
2739
  for (const file of jsFiles) {
2739
2740
  if (CONFIG_FILE_PATTERN.test(file.relativePath)) continue;
2741
+ if (SKIP_PATH.test(file.relativePath)) continue;
2742
+ const stripped = file.content.replace(/\/[^/\n]+\/[gimsuvy]*/g, '""').replace(/`[^`]*`/g, '""');
2740
2743
  const hasESM = ESM_PATTERN.test(file.content);
2741
- const hasCJS = CJS_PATTERN.test(file.content);
2744
+ const hasCJS = CJS_PATTERN.test(stripped);
2742
2745
  if (hasESM && hasCJS) {
2743
2746
  findings.push({
2744
2747
  analyzerId: "imports",
@@ -2908,8 +2911,11 @@ var NODE_BUILTINS = /* @__PURE__ */ new Set([
2908
2911
  ]);
2909
2912
  var JS_IMPORT_PATTERNS = [
2910
2913
  /(?:import|from)\s+['"]([^./][^'"]*)['"]/g,
2911
- /require\(\s*['"]([^./][^'"]*)['"]\s*\)/g
2914
+ /require\(\s*['"]([^./][^'"]*)['"]\s*\)/g,
2915
+ // Dynamic imports: await import("pkg") or import("pkg")
2916
+ /import\(\s*['"]([^./][^'"]*)['"]\s*\)/g
2912
2917
  ];
2918
+ var FIXTURE_PATH_PATTERN = /(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\]/i;
2913
2919
  function extractGoImports(content) {
2914
2920
  const imports = [];
2915
2921
  const singlePattern = /^import\s+"([^"]+)"/gm;
@@ -2998,7 +3004,7 @@ function analyzeJsDeps(ctx) {
2998
3004
  const imported = /* @__PURE__ */ new Set();
2999
3005
  const importLocations = /* @__PURE__ */ new Map();
3000
3006
  const jsFiles = ctx.files.filter(
3001
- (f) => f.language === "javascript" || f.language === "typescript"
3007
+ (f) => (f.language === "javascript" || f.language === "typescript") && !FIXTURE_PATH_PATTERN.test(f.relativePath)
3002
3008
  );
3003
3009
  for (const file of jsFiles) {
3004
3010
  for (const pattern of JS_IMPORT_PATTERNS) {
@@ -3856,11 +3862,12 @@ var SECURITY_PATTERNS = [
3856
3862
  id: "ssrf-risk",
3857
3863
  name: "SSRF risk",
3858
3864
  pattern: /(?:fetch|axios\.get|http\.get|requests\.get|httpClient)\s*\(\s*(?:[`'"].*\$\{|[^'"]*\+)/g,
3859
- severity: "warning",
3860
- confidence: 0.6,
3861
- message: "Potential SSRF: user-controlled value in URL construction",
3865
+ severity: "info",
3866
+ confidence: 0.4,
3867
+ message: "URL constructed from variable \u2014 review if the source is user-controlled",
3862
3868
  languages: "all",
3863
- tags: ["security", "ssrf"]
3869
+ tags: ["security", "ssrf"],
3870
+ negativeFilter: /(?:API_URL|BASE_URL|apiUrl|baseUrl|base\s*\+|endpoint|config\.|process\.env)/i
3864
3871
  },
3865
3872
  // === Python-specific ===
3866
3873
  {
@@ -3916,7 +3923,9 @@ var securityAnalyzer = {
3916
3923
  async analyze(ctx) {
3917
3924
  const findings = [];
3918
3925
  const projectLanguages = [...ctx.languageBreakdown.keys()];
3926
+ const PATTERN_DEF = /(?:pattern\s*:|regex\s*:|RegExp\s*\(|name\s*:|message\s*:|id\s*:|label\s*:)/;
3919
3927
  for (const file of ctx.files) {
3928
+ if (/(?:fixtures?|testdata|__fixtures__|__mocks__)[/\\]/i.test(file.relativePath)) continue;
3920
3929
  for (const pattern of SECURITY_PATTERNS) {
3921
3930
  if (pattern.languages !== "all") {
3922
3931
  if (!file.language || !pattern.languages.includes(file.language)) continue;
@@ -3924,10 +3933,11 @@ var securityAnalyzer = {
3924
3933
  const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
3925
3934
  let match;
3926
3935
  while ((match = regex.exec(file.content)) !== null) {
3936
+ const lineStart = file.content.lastIndexOf("\n", match.index) + 1;
3937
+ const lineEnd = file.content.indexOf("\n", match.index);
3938
+ const line = file.content.slice(lineStart, lineEnd === -1 ? void 0 : lineEnd);
3939
+ if (PATTERN_DEF.test(line)) continue;
3927
3940
  if (pattern.negativeFilter) {
3928
- const lineStart2 = file.content.lastIndexOf("\n", match.index) + 1;
3929
- const lineEnd2 = file.content.indexOf("\n", match.index);
3930
- const line = file.content.slice(lineStart2, lineEnd2 === -1 ? void 0 : lineEnd2);
3931
3941
  if (pattern.negativeFilter.test(line)) continue;
3932
3942
  }
3933
3943
  if (pattern.contextRequired) {
@@ -3939,9 +3949,7 @@ var securityAnalyzer = {
3939
3949
  if (!pattern.contextRequired.test(context)) continue;
3940
3950
  }
3941
3951
  const lineNum = getLineNumber(file.content, match.index);
3942
- const lineStart = file.content.lastIndexOf("\n", match.index) + 1;
3943
- const lineEnd = file.content.indexOf("\n", match.index);
3944
- const snippet = file.content.slice(lineStart, lineEnd === -1 ? void 0 : lineEnd).trim();
3952
+ const snippet = line.trim();
3945
3953
  findings.push({
3946
3954
  analyzerId: "security",
3947
3955
  severity: pattern.severity,