mobbdev 1.4.21 → 1.4.23

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.
@@ -417,6 +417,7 @@ var init_client_generates = __esm({
417
417
  return Vulnerability_Report_Issue_State_Enum2;
418
418
  })(Vulnerability_Report_Issue_State_Enum || {});
419
419
  Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((Vulnerability_Report_Issue_Tag_Enum3) => {
420
+ Vulnerability_Report_Issue_Tag_Enum3["AgenticRemediationInProgress"] = "AGENTIC_REMEDIATION_IN_PROGRESS";
420
421
  Vulnerability_Report_Issue_Tag_Enum3["AutogeneratedCode"] = "AUTOGENERATED_CODE";
421
422
  Vulnerability_Report_Issue_Tag_Enum3["AuxiliaryCode"] = "AUXILIARY_CODE";
422
423
  Vulnerability_Report_Issue_Tag_Enum3["FalsePositive"] = "FALSE_POSITIVE";
@@ -1926,7 +1927,8 @@ var init_getIssueType = __esm({
1926
1927
  ["TEST_CODE" /* TestCode */]: "The flagged code resides in a test-specific path or context. This categorization indicates that **it supports testing scenarios and is isolated from production use**.",
1927
1928
  ["UNFIXABLE" /* Unfixable */]: "The flagged code cannot be fixed",
1928
1929
  ["VENDOR_CODE" /* VendorCode */]: "The flagged code originates from a third-party library or dependency maintained externally. This categorization suggests that **the issue lies outside the application's direct control** and should be addressed by the vendor if necessary.",
1929
- ["SUPPRESSED" /* Suppressed */]: "Suppressed in the scan report."
1930
+ ["SUPPRESSED" /* Suppressed */]: "Suppressed in the scan report.",
1931
+ ["AGENTIC_REMEDIATION_IN_PROGRESS" /* AgenticRemediationInProgress */]: "Mobb is currently retrying remediation on this issue. The state will refresh automatically once the run finishes."
1930
1932
  };
1931
1933
  }
1932
1934
  });
@@ -4352,7 +4354,7 @@ import z27 from "zod";
4352
4354
 
4353
4355
  // src/commands/handleMobbLogin.ts
4354
4356
  import chalk2 from "chalk";
4355
- import Debug10 from "debug";
4357
+ import Debug11 from "debug";
4356
4358
 
4357
4359
  // src/utils/dirname.ts
4358
4360
  import fs from "fs";
@@ -4493,7 +4495,7 @@ var CliError = class extends Error {
4493
4495
  // src/commands/AuthManager.ts
4494
4496
  import crypto from "crypto";
4495
4497
  import os from "os";
4496
- import Debug9 from "debug";
4498
+ import Debug10 from "debug";
4497
4499
  import open from "open";
4498
4500
 
4499
4501
  // src/constants.ts
@@ -5439,6 +5441,48 @@ var languages = {
5439
5441
  init_client_generates();
5440
5442
  import { z as z11 } from "zod";
5441
5443
 
5444
+ // src/features/analysis/scm/shared/src/storedQuestionData/cpp/index.ts
5445
+ init_client_generates();
5446
+
5447
+ // src/features/analysis/scm/shared/src/storedQuestionData/cpp/commandInjection.ts
5448
+ var commandInjection = {
5449
+ isUnixShellCommandPart: {
5450
+ content: () => "Is the input data interpolated into a shell command (not the program name or shell structure)?",
5451
+ description: () => `\`system()\` / \`popen()\` hand the whole string to \`/bin/sh -c\`. Answer **yes** when the input is *data* placed into a fixed command, for example:
5452
+
5453
+ - \`sprintf(cmd, "grep %s file.txt", input); system(cmd);\`
5454
+ - \`sprintf(cmd, "ping -c 5 %s", input); system(cmd);\`
5455
+
5456
+ Answer **no** (the input is not plain data) when the input is:
5457
+
5458
+ 1. The program/executable itself:
5459
+ - \`system(input);\`
5460
+ - \`sprintf(cmd, "%s -x", input);\`
5461
+ 2. A command after a pipe or redirect:
5462
+ - \`sprintf(cmd, "cat file.txt | %s", input);\`
5463
+ 3. A part of a non-Unix or cross-platform shell command.
5464
+ 4. A part of embedded code in another language:
5465
+ - \`sprintf(cmd, "php -r \\"echo '%s';\\"", input);\`
5466
+ - \`sprintf(cmd, "awk '%s' file", input);\`
5467
+ 5. A flag/option that controls a tool's behaviour:
5468
+ - \`sprintf(cmd, "git --upload-pack %s", input);\``,
5469
+ guidance: () => "If yes and the command can run without a shell, it is rewritten to a no-shell argument-vector call (`posix_spawn`); if it needs the shell, the tainted argument is escaped in place so the shell keeps working. If the answer is no (the input controls the program or shell structure), there is no safe automatic rewrite, so the fix is withheld and the sink is left for manual review."
5470
+ },
5471
+ executableLocationPath: {
5472
+ content: () => "What is the absolute path of the directory containing the executable?",
5473
+ description: () => `When \`system()\` is rewritten to an \`execv()\` argument-vector call, the program is run by its path with **no \`$PATH\` search**, so a relative program name (e.g. \`tail\`) cannot be resolved and a poisoned \`PATH\` cannot be used to run a look-alike binary.
5474
+
5475
+ Provide the absolute directory that contains the executable (e.g. \`/usr/bin\`); the fix prepends it to the bare program name to form an absolute path.`,
5476
+ guidance: () => "Only asked when the program name in the command has no `/`. A program that is already an absolute or relative path (contains `/`) is used as written."
5477
+ }
5478
+ };
5479
+
5480
+ // src/features/analysis/scm/shared/src/storedQuestionData/cpp/index.ts
5481
+ var vulnerabilities11 = {
5482
+ ["CMDi" /* CmDi */]: commandInjection
5483
+ };
5484
+ var cpp_default = vulnerabilities11;
5485
+
5442
5486
  // src/features/analysis/scm/shared/src/storedQuestionData/csharp/index.ts
5443
5487
  init_client_generates();
5444
5488
 
@@ -5735,7 +5779,7 @@ var xxe = {
5735
5779
  };
5736
5780
 
5737
5781
  // src/features/analysis/scm/shared/src/storedQuestionData/csharp/index.ts
5738
- var vulnerabilities11 = {
5782
+ var vulnerabilities12 = {
5739
5783
  ["LOG_FORGING" /* LogForging */]: logForging,
5740
5784
  ["SSRF" /* Ssrf */]: ssrf2,
5741
5785
  ["XXE" /* Xxe */]: xxe,
@@ -5756,7 +5800,7 @@ var vulnerabilities11 = {
5756
5800
  ["SQL_Injection" /* SqlInjection */]: sqlInjection2,
5757
5801
  ["REQUEST_PARAMETERS_BOUND_VIA_INPUT" /* RequestParametersBoundViaInput */]: requestParametersBoundViaInput
5758
5802
  };
5759
- var csharp_default2 = vulnerabilities11;
5803
+ var csharp_default2 = vulnerabilities12;
5760
5804
 
5761
5805
  // src/features/analysis/scm/shared/src/storedQuestionData/go/index.ts
5762
5806
  init_client_generates();
@@ -5789,18 +5833,18 @@ var websocketMissingOriginCheck = {
5789
5833
  };
5790
5834
 
5791
5835
  // src/features/analysis/scm/shared/src/storedQuestionData/go/index.ts
5792
- var vulnerabilities12 = {
5836
+ var vulnerabilities13 = {
5793
5837
  ["LOG_FORGING" /* LogForging */]: logForging2,
5794
5838
  ["MISSING_SSL_MINVERSION" /* MissingSslMinversion */]: missingSslMinversion,
5795
5839
  ["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: websocketMissingOriginCheck
5796
5840
  };
5797
- var go_default2 = vulnerabilities12;
5841
+ var go_default2 = vulnerabilities13;
5798
5842
 
5799
5843
  // src/features/analysis/scm/shared/src/storedQuestionData/java/index.ts
5800
5844
  init_client_generates();
5801
5845
 
5802
5846
  // src/features/analysis/scm/shared/src/storedQuestionData/java/commandInjection.ts
5803
- var commandInjection = {
5847
+ var commandInjection2 = {
5804
5848
  isUnixShellCommandPart: {
5805
5849
  content: () => "Is the input part of Unix shell command?",
5806
5850
  description: () => `For example:
@@ -6254,10 +6298,10 @@ var xxe2 = {
6254
6298
  };
6255
6299
 
6256
6300
  // src/features/analysis/scm/shared/src/storedQuestionData/java/index.ts
6257
- var vulnerabilities13 = {
6301
+ var vulnerabilities14 = {
6258
6302
  ["SQL_Injection" /* SqlInjection */]: sqlInjection3,
6259
6303
  ["CMDi_relative_path_command" /* CmDiRelativePathCommand */]: relativePathCommand,
6260
- ["CMDi" /* CmDi */]: commandInjection,
6304
+ ["CMDi" /* CmDi */]: commandInjection2,
6261
6305
  ["CONFUSING_NAMING" /* ConfusingNaming */]: confusingNaming,
6262
6306
  ["ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */]: errorConditionWithoutAction,
6263
6307
  ["XXE" /* Xxe */]: xxe2,
@@ -6282,7 +6326,7 @@ var vulnerabilities13 = {
6282
6326
  ["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: erroneousStringCompare,
6283
6327
  ["DUPLICATED_STRINGS" /* DuplicatedStrings */]: duplicatedStrings
6284
6328
  };
6285
- var java_default2 = vulnerabilities13;
6329
+ var java_default2 = vulnerabilities14;
6286
6330
 
6287
6331
  // src/features/analysis/scm/shared/src/storedQuestionData/js/index.ts
6288
6332
  init_client_generates();
@@ -6297,7 +6341,7 @@ var csrf2 = {
6297
6341
  };
6298
6342
 
6299
6343
  // src/features/analysis/scm/shared/src/storedQuestionData/js/commandInjection.ts
6300
- var commandInjection2 = {
6344
+ var commandInjection3 = {
6301
6345
  isCommandExecutable: {
6302
6346
  content: () => "Commands can be intrinsically unsafe if they call out to other executables or run arbitary code",
6303
6347
  description: () => `Does the command fall into one of the following categories:
@@ -6611,8 +6655,8 @@ var xss3 = {
6611
6655
  };
6612
6656
 
6613
6657
  // src/features/analysis/scm/shared/src/storedQuestionData/js/index.ts
6614
- var vulnerabilities14 = {
6615
- ["CMDi" /* CmDi */]: commandInjection2,
6658
+ var vulnerabilities15 = {
6659
+ ["CMDi" /* CmDi */]: commandInjection3,
6616
6660
  ["GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */]: graphqlDepthLimit,
6617
6661
  ["INSECURE_RANDOMNESS" /* InsecureRandomness */]: insecureRandomness2,
6618
6662
  ["SSRF" /* Ssrf */]: ssrf4,
@@ -6634,7 +6678,7 @@ var vulnerabilities14 = {
6634
6678
  ["HARDCODED_DOMAIN_IN_HTML" /* HardcodedDomainInHtml */]: hardcodedDomainInHtml,
6635
6679
  ["CSRF" /* Csrf */]: csrf2
6636
6680
  };
6637
- var js_default = vulnerabilities14;
6681
+ var js_default = vulnerabilities15;
6638
6682
 
6639
6683
  // src/features/analysis/scm/shared/src/storedQuestionData/python/index.ts
6640
6684
  init_client_generates();
@@ -6708,7 +6752,7 @@ var uncheckedLoopCondition3 = {
6708
6752
  };
6709
6753
 
6710
6754
  // src/features/analysis/scm/shared/src/storedQuestionData/python/index.ts
6711
- var vulnerabilities15 = {
6755
+ var vulnerabilities16 = {
6712
6756
  ["CSRF" /* Csrf */]: csrf2,
6713
6757
  ["LOG_FORGING" /* LogForging */]: logForging5,
6714
6758
  ["OPEN_REDIRECT" /* OpenRedirect */]: openRedirect3,
@@ -6717,7 +6761,7 @@ var vulnerabilities15 = {
6717
6761
  ["MISSING_ENCODING_FILE_OPEN" /* MissingEncodingFileOpen */]: missingEncoding,
6718
6762
  ["SSRF" /* Ssrf */]: ssrf5
6719
6763
  };
6720
- var python_default2 = vulnerabilities15;
6764
+ var python_default2 = vulnerabilities16;
6721
6765
 
6722
6766
  // src/features/analysis/scm/shared/src/storedQuestionData/xml/index.ts
6723
6767
  init_client_generates();
@@ -6734,10 +6778,10 @@ A value too high will cause performance issues up to and including denial of ser
6734
6778
  };
6735
6779
 
6736
6780
  // src/features/analysis/scm/shared/src/storedQuestionData/xml/index.ts
6737
- var vulnerabilities16 = {
6781
+ var vulnerabilities17 = {
6738
6782
  ["WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */]: unboundedOccurrences
6739
6783
  };
6740
- var xml_default2 = vulnerabilities16;
6784
+ var xml_default2 = vulnerabilities17;
6741
6785
 
6742
6786
  // src/features/analysis/scm/shared/src/storedQuestionData/yaml/index.ts
6743
6787
  init_client_generates();
@@ -6770,12 +6814,12 @@ var writableFilesystemService = {
6770
6814
  };
6771
6815
 
6772
6816
  // src/features/analysis/scm/shared/src/storedQuestionData/yaml/index.ts
6773
- var vulnerabilities17 = {
6817
+ var vulnerabilities18 = {
6774
6818
  ["PORT_ALL_INTERFACES" /* PortAllInterfaces */]: portAllInterfaces,
6775
6819
  ["WRITABLE_FILESYSTEM_SERVICE" /* WritableFilesystemService */]: writableFilesystemService,
6776
6820
  ["NO_NEW_PRIVILEGES" /* NoNewPrivileges */]: noNewPrivileges
6777
6821
  };
6778
- var yaml_default = vulnerabilities17;
6822
+ var yaml_default = vulnerabilities18;
6779
6823
 
6780
6824
  // src/features/analysis/scm/shared/src/storedQuestionData/index.ts
6781
6825
  var StoredQuestionDataItemZ = z11.object({
@@ -6790,6 +6834,7 @@ var languages2 = {
6790
6834
  ["CSharp" /* CSharp */]: csharp_default2,
6791
6835
  ["Python" /* Python */]: python_default2,
6792
6836
  ["Go" /* Go */]: go_default2,
6837
+ ["Cpp" /* Cpp */]: cpp_default,
6793
6838
  ["YAML" /* Yaml */]: yaml_default
6794
6839
  };
6795
6840
 
@@ -7562,7 +7607,7 @@ var GQLClient = class {
7562
7607
  };
7563
7608
 
7564
7609
  // src/features/analysis/graphql/tracy-batch-upload.ts
7565
- import Debug8 from "debug";
7610
+ import Debug9 from "debug";
7566
7611
 
7567
7612
  // src/utils/sanitize-sensitive-data.ts
7568
7613
  import { OpenRedaction } from "@openredaction/openredaction";
@@ -7738,16 +7783,36 @@ async function sanitizeDataWithCounts(obj, options) {
7738
7783
  // src/utils/with-timeout.ts
7739
7784
  import { setTimeout as delay } from "timers/promises";
7740
7785
 
7786
+ // src/features/analysis/graphql/s3-raw-data-upload.ts
7787
+ import { setTimeout as sleep2 } from "timers/promises";
7788
+ import Debug8 from "debug";
7789
+
7741
7790
  // src/features/analysis/upload-file.ts
7742
7791
  import Debug7 from "debug";
7743
7792
  import fetch3, { File, fileFrom, FormData } from "node-fetch";
7744
7793
  var debug8 = Debug7("mobbdev:upload-file");
7794
+ var S3UploadError = class extends Error {
7795
+ constructor(status, s3Code, s3Message) {
7796
+ super(`Failed to upload the file: ${status}`);
7797
+ this.status = status;
7798
+ this.s3Code = s3Code;
7799
+ this.s3Message = s3Message;
7800
+ this.name = "S3UploadError";
7801
+ }
7802
+ };
7803
+ function parseS3ErrorBody(body) {
7804
+ return {
7805
+ code: body.match(/<Code>([^<]+)<\/Code>/)?.[1],
7806
+ message: body.match(/<Message>([^<]+)<\/Message>/)?.[1]
7807
+ };
7808
+ }
7745
7809
  async function uploadFile({
7746
7810
  file,
7747
7811
  url,
7748
7812
  uploadKey,
7749
7813
  uploadFields,
7750
- logger
7814
+ logger,
7815
+ signal
7751
7816
  }) {
7752
7817
  const logInfo = logger || ((_message, _data) => {
7753
7818
  });
@@ -7769,25 +7834,55 @@ async function uploadFile({
7769
7834
  } else {
7770
7835
  debug8("upload file from buffer");
7771
7836
  logInfo(`FileUpload: upload file from buffer`);
7772
- form.append("file", new File([new Uint8Array(file)], "file"));
7837
+ form.append(
7838
+ "file",
7839
+ new File(
7840
+ [
7841
+ new Uint8Array(
7842
+ file.buffer,
7843
+ file.byteOffset,
7844
+ file.byteLength
7845
+ )
7846
+ ],
7847
+ "file"
7848
+ )
7849
+ );
7773
7850
  }
7774
7851
  const agent = getProxyAgent(url);
7775
7852
  const response = await fetch3(url, {
7776
7853
  method: "POST",
7777
7854
  body: form,
7778
- agent
7855
+ agent,
7856
+ signal
7779
7857
  });
7780
7858
  if (!response.ok) {
7781
- debug8("error from S3 %s %s", response.body, response.status);
7782
- logInfo(`FileUpload: error from S3 ${response.body} ${response.status}`);
7783
- throw new Error(`Failed to upload the file: ${response.status}`);
7859
+ let bodyText = "";
7860
+ try {
7861
+ bodyText = await response.text();
7862
+ } catch {
7863
+ }
7864
+ const { code, message } = parseS3ErrorBody(bodyText);
7865
+ debug8(
7866
+ "error from S3 status=%d code=%s message=%s",
7867
+ response.status,
7868
+ code,
7869
+ message
7870
+ );
7871
+ logInfo(
7872
+ `FileUpload: error from S3 status=${response.status} code=${code ?? "unknown"}`
7873
+ );
7874
+ throw new S3UploadError(response.status, code, message);
7784
7875
  }
7785
7876
  debug8("upload file done");
7786
7877
  logInfo(`FileUpload: upload file done`);
7787
7878
  }
7788
7879
 
7880
+ // src/features/analysis/graphql/s3-raw-data-upload.ts
7881
+ var debug9 = Debug8("mobbdev:tracy-s3-upload");
7882
+ var URL_REFRESH_MS = 20 * 60 * 1e3;
7883
+
7789
7884
  // src/features/analysis/graphql/tracy-batch-upload.ts
7790
- var debug9 = Debug8("mobbdev:tracy-batch-upload");
7885
+ var debug10 = Debug9("mobbdev:tracy-batch-upload");
7791
7886
 
7792
7887
  // src/mcp/services/types.ts
7793
7888
  function buildLoginUrl(baseUrl, loginId, hostname, context) {
@@ -7820,7 +7915,7 @@ function createConfigStore(defaultValues = { apiToken: "" }) {
7820
7915
  var configStore = createConfigStore();
7821
7916
 
7822
7917
  // src/commands/AuthManager.ts
7823
- var debug10 = Debug9("mobbdev:auth");
7918
+ var debug11 = Debug10("mobbdev:auth");
7824
7919
  var LOGIN_MAX_WAIT = 2 * 60 * 1e3;
7825
7920
  var LOGIN_CHECK_DELAY = 2 * 1e3;
7826
7921
  var _AuthManager = class _AuthManager {
@@ -7850,7 +7945,7 @@ var _AuthManager = class _AuthManager {
7850
7945
  return false;
7851
7946
  }
7852
7947
  if (_AuthManager.browserCooldownMs > 0 && Date.now() - _AuthManager.lastBrowserOpenTime < _AuthManager.browserCooldownMs) {
7853
- debug10("browser cooldown active, skipping open");
7948
+ debug11("browser cooldown active, skipping open");
7854
7949
  return false;
7855
7950
  }
7856
7951
  open(this.currentBrowserUrl);
@@ -7903,7 +7998,7 @@ var _AuthManager = class _AuthManager {
7903
7998
  const result = await this.checkAuthentication();
7904
7999
  this.authenticated = result.isAuthenticated;
7905
8000
  if (!result.isAuthenticated) {
7906
- debug10("isAuthenticated: false \u2014 %s (%s)", result.message, result.reason);
8001
+ debug11("isAuthenticated: false \u2014 %s (%s)", result.message, result.reason);
7907
8002
  }
7908
8003
  }
7909
8004
  return this.authenticated;
@@ -7991,9 +8086,9 @@ var _AuthManager = class _AuthManager {
7991
8086
  return null;
7992
8087
  } catch (error) {
7993
8088
  if (isTransientError(error)) {
7994
- debug10("getApiToken: transient error, will retry");
8089
+ debug11("getApiToken: transient error, will retry");
7995
8090
  } else {
7996
- debug10("getApiToken: unexpected error: %O", error);
8091
+ debug11("getApiToken: unexpected error: %O", error);
7997
8092
  }
7998
8093
  return null;
7999
8094
  }
@@ -8046,7 +8141,7 @@ __publicField(_AuthManager, "lastBrowserOpenTime", 0);
8046
8141
  var AuthManager = _AuthManager;
8047
8142
 
8048
8143
  // src/commands/handleMobbLogin.ts
8049
- var debug11 = Debug10("mobbdev:commands");
8144
+ var debug12 = Debug11("mobbdev:commands");
8050
8145
  var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk2.bgBlue(
8051
8146
  "press any key to continue"
8052
8147
  )};`;
@@ -8056,7 +8151,7 @@ async function getAuthenticatedGQLClient({
8056
8151
  apiUrl,
8057
8152
  webAppUrl
8058
8153
  }) {
8059
- debug11(
8154
+ debug12(
8060
8155
  "getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
8061
8156
  apiUrl || "undefined",
8062
8157
  webAppUrl || "undefined"
@@ -8080,7 +8175,7 @@ async function handleMobbLogin({
8080
8175
  loginPath,
8081
8176
  authManager
8082
8177
  }) {
8083
- debug11(
8178
+ debug12(
8084
8179
  "handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
8085
8180
  apiUrl || "fallback",
8086
8181
  apiUrl || "fallback",
@@ -8096,7 +8191,7 @@ async function handleMobbLogin({
8096
8191
  return authManager.getGQLClient();
8097
8192
  }
8098
8193
  if (authResult.reason === "unknown") {
8099
- debug11("Auth check returned unknown: %s", authResult.message);
8194
+ debug12("Auth check returned unknown: %s", authResult.message);
8100
8195
  throw new CliError(`Cannot verify authentication: ${authResult.message}`);
8101
8196
  }
8102
8197
  if (apiKey) {