checkmarx-ts / CxAnalytix

Exports vulnerability scan data from the Checkmarx SAST platform for use in analytical tools.
Other
20 stars 10 forks source link

SocketException when processing large amount of data in a single run #22

Closed benjaminstokes closed 4 years ago

benjaminstokes commented 4 years ago

Description

When running CxAnalytix with lots of scan data to process (in this case 52 projects with 48 scans) an exception can occur that causes all data to not be extracted due to a System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.

Expected Behavior

No exceptions should occur regardless of how many projects or scans are being extracted in a single run or lifetime of the CxAnalytix process.

Actual Behavior

PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> dotnet CxAnalytixCLI.dll
[2020-08-11 21:21:31,419]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-08-11 21:21:31,432]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\cxanalytix\artifacts\Release
[2020-08-11 21:21:31,884]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-08-11 21:21:32,299]  WARN [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - Database CxAnalytix does not exist, it will be created.
[2020-08-11 21:21:32,316]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Detail
[2020-08-11 21:21:32,343]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Summary
[2020-08-11 21:21:32,354]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Summary
[2020-08-11 21:21:32,365]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Detail
[2020-08-11 21:21:32,376]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Project_Info
[2020-08-11 21:21:32,386]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Policy_Violations
[2020-08-11 21:21:32,408]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Policy data is not available.
System.InvalidOperationException: Unable to retrieve policies.
   at CxRestClient.CxMnoPolicies.GetAllPolicies(CxRestContext ctx, CancellationToken token) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxMnoPolicies.cs:line 128
   at CxAnalytix.TransformLogic.Transformer..ctor(CxRestContext ctx, CancellationToken token, String previousStatePath) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 260
[2020-08-11 21:21:32,856]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 48 projects are targets for check for new scans. Since last scan: 0 projects removed, 48 new projects.
[2020-08-11 21:21:33,437]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 52 scans to check in 48 projects since 8/11/2020 9:21:32 PM.
[2020-08-11 21:23:00,476]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000006 in project 7: NodeGoat_sandbox.
System.AggregateException: One or more errors occurred. (Only one usage of each socket address (protocol/network address/port) is normally permitted) ---> System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenStatus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)<---

[2020-08-11 21:23:00,494]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000004 in project 5: dvna_sandbox.
System.AggregateException: One or more errors occurred. (Only one usage of each socket address (protocol/network address/port) is normally permitted) ---> System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at CxRestClient.CxSastGenerateScanReport.GetGeneratedReportId(CxRestContext ctx, CancellationToken token, String scanId, ReportTypes type) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastGenerateScanReport.cs:line 63
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 26
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)<---

[2020-08-11 21:23:00,515]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000001 in project 2: WebGoat_policy.
System.AggregateException: One or more errors occurred. (Only one usage of each socket address (protocol/network address/port) is normally permitted) ---> System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at CxRestClient.CxSastGenerateScanReport.GetGeneratedReportId(CxRestContext ctx, CancellationToken token, String scanId, ReportTypes type) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastGenerateScanReport.cs:line 63
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 26
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)<---

Reproduction

CxAnalytix 1.1.3 on Windows Server 2016. Starting with a clean State File and needing to extract data for 52 projects and 48 scans. Configuration is set for MongoDB:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="CxCredentials" type="CxAnalytix.Configuration.CxCredentials, Configuration" />
    <section name="CxConnection" type="CxAnalytix.Configuration.CxConnection, Configuration" />
    <section name="CxAnalyticsService" type="CxAnalytix.Configuration.CxAnalyticsService, Configuration" />
    <section name="CxLogOutput" type="CxAnalytix.Out.Log4NetOutput.LogOutputConfig, Log4NetOutput" />
    <section name="CxMongoOutput" type="CxAnalytix.Out.MongoDBOutput.MongoOutConfig, MongoDBOutput" />
  </configSections>

  <!-- Common config parameters -->
  <CxConnection URL="http://localhost"
                mnoURL=""
                TimeoutSeconds="600" ValidateCertificates="true" />
  <CxCredentials configProtectionProvider="DataProtectionConfigurationProvider">
    <EncryptedData>
      <CipherData>
        <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAD+Yfz3TTtkuNUwiA2mnaNQQAAAACAAAAAAAQZgAAAAEAACAAAABEFil6yJornAfayWri4jhnYx8ZcVKlCbdK0MKf0OYbPQAAAAAOgAAAAAIAACAAAAAoSneyAzYRay+umoLa1CEvdb/54SM3v6CwWl8QMcgPOZAAAADSspNbRLZr9vwTmqOeZhm05gVNs3yONMWuKvhfwodTOF7jGtg9uHVbc5lH8cpNxU7Qb072JAjiiCYrAjy1aCjMO5NH0ibJViL0n9euH2jJz6mibUo0VNoNfid8KQhRZqogivlzpL/rEOSOdX0qEzu3ABu35g9knhcCb8wL2kwawXAIn3vYYE8vAszERfZ8fbpAAAAACU6pegd1dCoitWECWzFd5oPxW2BLsCRkJqG30yqFsmwD0jKEh8WWyK5QPVxZ9x8TURIliyJdtMhLK/yHGKiq6Q==</CipherValue>
      </CipherData>
    </EncryptedData>
  </CxCredentials>
  <CxAnalyticsService ConcurrentThreads="2" StateDataStoragePath=""
                      ProcessPeriodMinutes="120"
                      OutputFactoryClassPath="CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory, MongoDBOutput"
                      SASTScanSummaryRecordName="RECORD_SAST_Scan_Summary"
                      SASTScanDetailRecordName="RECORD_SAST_Scan_Detail"
                      SCAScanSummaryRecordName="RECORD_SCA_Scan_Summary"
                      SCAScanDetailRecordName="RECORD_SCA_Scan_Detail"
                      ProjectInfoRecordName="RECORD_Project_Info"
                      PolicyViolationsRecordName="RECORD_Policy_Violations"
                      />

  <!-- Specific output method configuration parameters -->
  <CxLogOutput DataRetentionDays="3" OutputRoot="logs\">
    <PurgeSpecs>
      <spec MatchSpec="*.log.*" />
    </PurgeSpecs>
  </CxLogOutput>

  <CxMongoOutput ConnectionString="mongodb://localhost:27017/CxAnalytix">
    <!-- This section is optional -->
    <GeneratedShardKeys>
      <!-- Each of these are optional -->
      <Spec KeyName="pkey" CollectionName="SAST_Scan_Summary" FormatSpec="{ScanType}-{ScanFinished:yyyy-dddd}"  />
      <Spec KeyName="pkey" CollectionName="SAST_Scan_Detail" FormatSpec="{ScanType}-{QueryGroup}-{ScanFinished:yyyy-dddd}" />
    </GeneratedShardKeys>
  </CxMongoOutput>

</configuration>

Build the tool as per the tutorial and run the command line. Notice that the exception (above) occurs and you do not have all of your data loaded into MongoDB.

Note:

Initial research indicates this is a known issue with HttpClient and the solution is instantiate it once (singleton) and use many times.

This issue report from Azure Functions seems to be relevant to this bug report in CxAnalytix: https://github.com/Azure/azure-functions-host/issues/1806

Environment Details

CxAnalytix v1.1.3 on Server 2016.

benjaminstokes commented 4 years ago

Checkmarx version is 8.9 HF 0. This rather long script is what I used to generate the test data set i'm working with

# Create projects with the Checkmarx CLI
$cxUser="checkmarx"
$cxPass="redacted"
$cxServer="localhost"

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
$progressPreference = 'silentlyContinue'

# Install the Checkmarx CLI
md -force c:\programdata\checkmarx\cli
$cli_url="https://download.checkmarx.com/9.0.0/Plugins/CxConsolePlugin-2020.2.18.zip"
$cli_zip=$cli_url.Substring($cli_url.LastIndexOf("/") + 1)
invoke-webrequest -uri "${cli_url}" -outfile "C:\programdata\checkmarx\cli\${cli_zip}"
cd "c:\programdata\checkmarx\cli\"
Expand-Archive "c:\programdata\checkmarx\cli\${cli_zip}" -DestinationPath "c:\programdata\checkmarx\cli\"

cd c:\programdata\checkmarx\cli\

Class CxArmPolicyManagementApiClient {
  [string] $username 
  [string] $password 
  [string] $url
  [string] $token 
  [string] $apiscope = "sast_rest_api cxarm_api"
  [string] $clientid = "resource_owner_client"
  [string] $clientsecret = "014DF517-39D1-4453-B7B3-9930C563627C"

  CxArmPolicyManagementApiClient([string] $username, [string] $password, [string] $url) {
    $this.username = $username
    $this.password = $password
    $this.url = $url
  }

  Login() {
    $body = @{
        username = $this.username
        password = $this.password
        grant_type = "password"
        scope = $this.apiscope
        client_id = $this.clientid
        client_secret = $this.clientsecret
    }
    try {
        $response = Invoke-RestMethod -uri "$($this.url)/cxrestapi/auth/identity/connect/token" -method post -body $body -contenttype 'application/x-www-form-urlencoded' -UseBasicParsing
    } catch {
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        throw "Cannot Get OAuth2 Token"
    }

    $this.token = "$($response.token_type) $($response.access_token)"
  }

  [PSObject] GET([string] $url) {
    $headers = @{
        Authorization = $this.token
        Accept = "application/json;v=1.0"
    }
    try {
        $response = Invoke-RestMethod -uri "$($this.url)${url}" -method get -headers $headers -UseBasicParsing
        return $response
    } catch {
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        throw "An error has occured on GET $url"
    }
  }

  [PSObject] POST([string] $url, $body) {
    $body_json = ($body | ConvertTo-Json -Depth 10)
    $headers = @{
        Authorization = $this.token       
    }
    try {
        $response = Invoke-RestMethod -uri "$($this.url)${url}" -method post -headers $headers -UseBasicParsing -Body $body_json -ContentType "application/json;v=1.0"
        return $response
    } catch {
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        throw "An error has occured on POST $url with $body_json"
    }
  }

  [PSObject] PUTliteral([string] $url, $body) {
    $body_json = $body
    $headers = @{
        Authorization = $this.token       
    }
    try {
        $response = Invoke-RestMethod -uri "$($this.url)${url}" -method put -headers $headers -UseBasicParsing -Body $body_json -ContentType "application/json;v=1.0"
        return $response
    } catch {
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        throw "An error has occured on PUT $url with $body_json"
    }
  }

  [PSObject] PUT([string] $url, $body) {
    $body_json = ($body | ConvertTo-Json -Depth 10)
    $headers = @{
        Authorization = $this.token       
    }
    try {
        $response = Invoke-RestMethod -uri "$($this.url)${url}" -method put -headers $headers -UseBasicParsing -Body $body_json -ContentType "application/json;v=1.0"
        return $response
    } catch {
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        throw "An error has occured on PUT $url with $body_json"
    }
  }

  <######################
  #  Projects
  #######################>
  [PSObject] GetProjects() {
    return $this.GET("/cxarm/policymanager/projects")
  }
  [PSObject] GetPoliciesByProjectId($id) {
    return $this.GET("/cxarm/policymanager/projects/${id}/policies")
  }
  [PSObject] GetViolationsByProjectId($id) {
    return $this.GET("/cxarm/policymanager/projects/${id}/violations?provider=SAST")
  }
  [PSObject] UpdatePoliciesByProjectId ($projectId, $policyId) {
    $policies = "[ { `"policyId`": $policyId } ]"
    return $this.PUTliteral("/cxarm/policymanager/projects/${projectId}/policies", $policies)
  }

  <######################
  #  Policies
  #######################>
  [PSObject] GetPolicies() {
    return $this.GET("/cxarm/policymanager/policies")
  }
  [PSObject] FindPolicyIdByName([string] $name) {
    $policies = $this.GetPolicies()
    $policyId = $policies | where { $_.name -eq $name } | select -ExpandProperty id
    return $policyId
  }
  [PSObject] GetPoliciesById($id) {
    return $this.GET("/cxarm/policymanager/policies/${id}")
  }
  [PSObject] GetAssignedProjectsByPoliciyId($id) {
    return $this.GET("/cxarm/policymanager/policies/${id}/projects")
  }
  [PSObject] CreatePolicy ($policy) {
    return $this.POST("/cxarm/policymanager/policies", $policy)
  }

  <######################
  #  Rules
  #######################>
  [PSObject] GetRulesByPolicyId($id) {
    return $this.GET("/cxarm/policymanager/policies/${id}/rules")
  }

  <######################
  #  SAST - Projects
  #######################>
  [PSObject] GetSastProjects() {
    return $this.GET("/cxrestapi/projects")
  }
  [PSObject] FindProjectByName([string] $name) {
    $projects = $this.GetSastProjects()
    $projectId = $projects | where { $_.name -eq $name } | select -ExpandProperty id
    return $projectId
  }
  [PSObject] CreateProject($project) {
    return $this.POST("/cxrestapi/projects", $project)
  }

  [PSObject] UpdateProject($project, $id) {
    return $this.PUT("/cxrestapi/projects/${id}", $project)
  }

  <######################
  #  SAST - Teams
  #######################>

  [PSObject] GetTeams() {
    return $this.GET("/cxrestapi/auth/teams")
  }

  [string] FindTeamIdByName([string] $teamName) {
    $teams = $this.GetTeams()
    $teamid = $teams | where { $_.fullname -eq $teamName } | select -ExpandProperty id
    return $teamid
  }

  <######################
  #  SAST - Custom Fields
  #######################>

  [PSObject] GetCustomFields() {
    return $this.GET("/cxrestapi/customFields")
  }

  <######################
  #  SAST - Presets
  #######################>

  [PSObject] GetPresets() {
    return $this.GET("/cxrestapi/sast/presets")
  }
  [PSObject] GetPresetById($id) {
    return $this.GET("/cxrestapi/sast/presets/${id}")
  }
  [PSObject] FindPresetIdByName([string] $name) {
    $presets = $this.GetPresets()
    $presetId = $presets | where { $_.name -eq $name } | select -ExpandProperty id
    return $presetId
  }

  <######################
  #  SAST - Engine Configurations
  #######################>

  [PSObject] GetEngineConfigurations() {
    return $this.GET("/cxrestapi/sast/engineConfigurations")
  }
  [PSObject] GetEngineConfigurationById($id) {
    return $this.GET("/cxrestapi/sast/engineConfigurations/${id}")
  }
  [PSObject] FindEngineConfigurationIdByName([string] $name) {
    $engineConfigurations = $this.GetEngineConfigurations()
    $engineConfigurationId = $engineConfigurations | where { $_.name -eq $name } | select -ExpandProperty id
    return $engineConfigurationId
  }

  <######################
  #  SAST - Scans
  #######################>
  [PSObject] CreateScanSettings($settings) {
    return $this.POST("/cxrestapi/sast/scanSettings", $settings)
  }
}

Class CxWebServiceClient {
  [string] $username 
  [string] $password 
  [string] $url
  [string] $SessionId 
  $proxy

  CxWebServiceClient([string] $username, [string] $password, [string] $url) {
    $this.username = $username
    $this.password = $password
    $this.url = $url
    $this.proxy = New-WebServiceProxy -Uri "$($this.url)/CxWebInterface/Portal/CxWebService.asmx?wsdl"
  }

  Login() {
   $proxyType = $this.proxy.GetType().Namespace
   $credentials = new-object ("$proxyType.Credentials")
   $credentials.User = $this.username
   $credentials.Pass = $this.password
   $res = $this.proxy.Login($credentials, 1033) 
   $this.SessionId = $res.SessionId
  }

  [PSObject] SaveCustomFields($fields) {
    $customfields = @()
    $fields | ForEach-Object {
        $proxyType = $this.proxy.GetType().Namespace
        $customfield = New-Object ("$proxyType.CxWSCustomField")
        $customfield.Id = 0         # Not a mistake, really zero
        $customfield.Name = $_
        $customfields+=$customfield
    }

    $res = $this.proxy.SaveCustomFields($this.sessionId, $customfields)
    if($res.IsSuccesfull){
        Write-Host "Custom fields have been created" -ForegroundColor Green
    } else{
        Write-Host $res.ErrorMessage -ForegroundColor Red
    }

    return $res
  }

  [PSObject] CreateServiceProvider($name) {
    $res = $this.proxy.CreateNewServiceProvider($this.SessionId, $name, 1, 1, 1, 1, $null)
    if ($res.IsSuccesfull) { 
        Write-Host "Created Service Provider" -ForegroundColor Green
    } else { 
        Write-Host "Error creating service provider" -ForegroundColor Red
    }
    return $res
  }

  [PSObject] CreateCompany($name, $parentId) {
    $res = $this.proxy.CreateNewCompany($this.SessionId, $parentId, $name, 1, 1, 1, 1, $null)
    if ($res.IsSuccesfull) { 
        Write-Host "Created Company" -ForegroundColor Green
    } else { 
        Write-Host "Error creating company" -ForegroundColor Red
    }
    return $res
  }

  [PSObject] CreateTeam($name, $parentId) {
    $res = $this.proxy.CreateNewTeam($this.SessionId, $parentId, $name, $null)
    if ($res.IsSuccesfull) { 
        Write-Host "Created Team" -ForegroundColor Green
    } else { 
        Write-Host "Error creating team" -ForegroundColor Red
    }
    return $res
  }
}

$projects = @(
"https://github.com/appsecco/dvna",
"https://github.com/WebGoat/WebGoat",
"https://github.com/OWASP/NodeGoat"
"https://github.com/naudio/NAudio",
"https://github.com/nopSolutions/nopCommerce",
"https://github.com/lukencode/FluentEmail",
"https://github.com/ethicalhack3r/DVWA",
"https://github.com/notepad-plus-plus/notepad-plus-plus",
"https://github.com/appsecco/dvja",
"https://github.com/CSPF-Founder/JavaVulnerableLab",
"https://github.com/nvisium-jack-mannino/OWASP-GoatDroid-Project",
"https://github.com/interference-security/DVWS",
"https://github.com/snoopysecurity/dvws-node",
"https://github.com/htbridge/pivaa",
"https://github.com/payatu/diva-android",
"https://github.com/CSPF-Founder/DodoVulnerableBank",
"https://github.com/dineshshetty/Android-InsecureBankv2",
"https://github.com/dan7800/VulnerableAndroidAppOracle",
"https://github.com/CyberScions/Digitalbank",
"https://github.com/logicalhacking/DVHMA",
"https://github.com/bkimminich/juice-shop",
"https://github.com/prateek147/DVIA",
"https://github.com/prateek147/DVIA-v2",
"https://github.com/hclproducts/AltoroJ"
)

[CxArmPolicyManagementApiClient] $cxrest = [CxArmPolicyManagementApiClient]::New($cxUser, $cxPass, $cxServer)
$cxrest.Login()

[CxWebServiceClient] $cxWs = [CxWebServiceClient]::New($cxUser, $cxPass, "http://${cxServer}")
$cxWs.Login()

foreach ($url in $projects) {
  $projectName = $url.Substring($url.LastIndexOf("/") + 1)
  $CompanyId = $cxrest.FindTeamIdByName("\CxServer\serviceprovider\company\") 
  $existingTeam = $cxrest.FindTeamIdByName("\CxServer\serviceprovider\company\${projectName}\")
  if ($null -ne $existingTeam) {
    Write-Host "SKIPPED: $team already exists" -ForegroundColor Yellow
  } else {
      Write-Host "Created \CxServer\serviceprovider\company\${projectName}\" -ForegroundColor Green
      $res = $cxWs.CreateTeam("\CxServer\serviceprovider\company\${projectName}\", $CompanyId)
  }
}

foreach ($url in $projects) {
  $projectName = $url.Substring($url.LastIndexOf("/") + 1)
  .\runCxConsole.cmd AsyncScan -v -projectName "CxServer\serviceprovider\company\${projectName}\${projectName}_sandbox" -CxServer "${cxServer}"  -CxUser ${cxUser} -CxPassword ${cxPass} -LocationType GIT -LocationURL "$url" -LocationBranch "refs/heads/master" -ForceScan
}

foreach ($url in $projects) {
  $projectName = $url.Substring($url.LastIndexOf("/") + 1)
  .\runCxConsole.cmd AsyncScan -v -projectName "CxServer\serviceprovider\company\${projectName}_policy" -CxServer "${cxServer}"  -CxUser ${cxUser} -CxPassword ${cxPass} -LocationType GIT -LocationURL "$url" -LocationBranch "refs/heads/master" -ForceScan
}
benjaminstokes commented 4 years ago

The root cause appears to be that so many HttpClients are created that an exception occurs. I have created a rough patch that reuses a static HttpClient with or without SSL verification enabled however the pattern of the using statements in the CxRestClient namespace causes the static HttpClient to be disposed of.

When ConcurrentThreads is > 1 this patch causes multiple exceptions to be thrown which I think indicate HttpClient is not threadsafe when used as a static (duh?).

PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> dotnet CxAnalytixCLI.dll
[2020-08-12 01:58:26,968]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-08-12 01:58:26,983]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\cxanalytix\artifacts\Release
[2020-08-12 01:58:27,359]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-08-12 01:58:27,764]  WARN [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - Database CxAnalytix does not exist, it will be created.
[2020-08-12 01:58:27,784]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Detail
[2020-08-12 01:58:27,817]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Summary
[2020-08-12 01:58:27,827]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Summary
[2020-08-12 01:58:27,838]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Detail
[2020-08-12 01:58:27,847]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Project_Info
[2020-08-12 01:58:27,856]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Policy_Violations
[2020-08-12 01:58:27,875]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Policy data is not available.
System.InvalidOperationException: Unable to retrieve policies.
   at CxRestClient.CxMnoPolicies.GetAllPolicies(CxRestContext ctx, CancellationToken token) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxMnoPolicies.cs:line 124
   at CxAnalytix.TransformLogic.Transformer..ctor(CxRestContext ctx, CancellationToken token, String previousStatePath) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 260
[2020-08-12 01:58:28,198]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 48 projects are targets for check for new scans. Since last scan: 0 projects removed, 48 new projects.
[2020-08-12 01:58:28,591]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 52 scans to check in 48 projects since 8/12/2020 1:58:27 AM.
[2020-08-12 01:58:29,720]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000005 in project 6: WebGoat_sandbox.
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
   at System.Net.Http.Headers.HttpHeaders.AddHeaders(HttpHeaders sourceHeaders)
   at System.Net.Http.Headers.HttpRequestHeaders.AddHeaders(HttpHeaders sourceHeaders)
   at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenStatus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:29,915]  WARN [6] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000032 in project 29: nopCommerce_policy.
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
   at System.Net.Http.Headers.HttpHeaders.AddHeaders(HttpHeaders sourceHeaders)
   at System.Net.Http.Headers.HttpRequestHeaders.AddHeaders(HttpHeaders sourceHeaders)
   at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenStatus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:30,128]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000050 in project 47: DVIA-v2_policy.
System.ArgumentException: An item with the same key has already been added. Key: System.Net.Http.Headers.HeaderDescriptor
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(HeaderDescriptor descriptor, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaderValueCollection`1.Add(T item)
   at CxRestClient.CxRestContext.ClientFactory.CreateGenericClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 80
   at CxRestClient.CxRestContext.ClientFactory.CreateSastClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 54
atus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:30,832]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000045 in project 42: VulnerableAndroidAppOracle_policy.
System.ArgumentException: An item with the same key has already been added. Key: System.Net.Http.Headers.HeaderDescriptor
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(HeaderDescriptor descriptor, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaderValueCollection`1.Add(T item)
   at CxRestClient.CxRestContext.ClientFactory.CreateGenericClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 80
   at CxRestClient.CxRestContext.ClientFactory.CreateSastClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 54
atus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:33,723]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000051 in project 48: AltoroJ_policy.
System.ArgumentException: An item with the same key has already been added. Key: System.Net.Http.Headers.HeaderDescriptor
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(HeaderDescriptor descriptor, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaderValueCollection`1.Add(T item)
   at CxRestClient.CxRestContext.ClientFactory.CreateGenericClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 80
   at CxRestClient.CxRestContext.ClientFactory.CreateSastClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 54
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenSt
atus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:35,991]  WARN [13] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000048 in project 45: juice-shop_policy.
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection'
s state is no longer correct.
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(HeaderDescriptor descriptor, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaderValueCollection`1.Add(T item)
   at CxRestClient.CxRestContext.ClientFactory.CreateGenericClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 80
   at CxRestClient.CxRestContext.ClientFactory.CreateSastClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 54
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenSt
atus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
[2020-08-12 01:58:35,991]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Error attempting to retrieve the SAST XML report for 1000049 in project 46: DVIA_policy.
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection'
s state is no longer correct.
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
   at System.Net.Http.Headers.HttpHeaders.GetOrCreateHeaderInfo(HeaderDescriptor descriptor, Boolean parseRawValues)
   at System.Net.Http.Headers.HttpHeaderValueCollection`1.Add(T item)
   at CxRestClient.CxRestContext.ClientFactory.CreateGenericClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 80
   at CxRestClient.CxRestContext.ClientFactory.CreateSastClient() in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxRestContext.cs:line 54
   at CxRestClient.CxSastScanReportGenStatus.GetReportGenerationStatus(CxRestContext ctx, CancellationToken token, String reportId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastScanReportGenSt
atus.cs:line 44
   at CxRestClient.CxSastXmlReport.GetXmlReport(CxRestContext ctx, CancellationToken token, String scanId) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxSastXmlReport.cs:line 33
   at CxAnalytix.TransformLogic.Transformer.SastReportOutput(ScanDescriptor scan, Transformer inst) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 68
PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> ^C
PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> ^C
PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> ^C
PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> ^C

If I set concurrent threads to 1 the program runs successfully without error. Note in this example data set (52 projects w/ 48 scans) the program makes 34807 calls to MakeClient (presumably, to make a API call) which would represent an HttpClient instantiation of not using a static. Perhaps this volume of clients is what would be consuming so many outbound ports causing the original SocketException error message reported.

PS C:\programdata\checkmarx\cxanalytix\artifacts\Release> dotnet CxAnalytixCLI.dll
[2020-08-12 02:01:59,315]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-08-12 02:01:59,327]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\cxanalytix\artifacts\Release
[2020-08-12 02:01:59,646]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-08-12 02:02:00,074]  WARN [1] [CxAnalytix.TransformLogic.Transformer] (?:?) - Policy data is not available.
System.InvalidOperationException: Unable to retrieve policies.
   at CxRestClient.CxMnoPolicies.GetAllPolicies(CxRestContext ctx, CancellationToken token) in c:\programdata\checkmarx\CxAnalytix\CxRestClient\CxMnoPolicies.cs:line 124
   at CxAnalytix.TransformLogic.Transformer..ctor(CxRestContext ctx, CancellationToken token, String previousStatePath) in c:\programdata\checkmarx\CxAnalytix\TransformLogic\Transformer.cs:line 260
[2020-08-12 02:02:00,377]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 48 projects are targets for check for new scans. Since last scan: 0 projects removed, 48 new projects.
[2020-08-12 02:02:00,776]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 52 scans to check in 48 projects since 8/12/2020 2:02:00 AM.
[2020-08-12 02:04:38,565]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Rest client requested: 34807
[2020-08-12 02:04:38,565]  INFO [1] [CxAnalytixCLI.Program] (?:?) - End
benjaminstokes commented 4 years ago

A sketch of changing the HttpClient to a static that works in a single thread nature is in https://github.com/checkmarx-ts/CxAnalytix/pull/24.

This still has issues with multiple concurrent threads but I think the fix for that is beyond my ability at the moment and may need more significant changes to the way clients are generated for SAST and MNO.

nleach999 commented 4 years ago

The use of HttpClient needs to be refactored due to the static requirement. (I guess I missed that in the API docs....). Some of our GET ops require different media types (Json/XML) which isn't supported by the API on a per-request basis as far as I can tell, so that will be something I'll have to work out.

nleach999 commented 4 years ago

Actually, I see the correct API in looking at it closer. It won't be too difficult to fix.

benjaminstokes commented 4 years ago

@nleach999 I tested the https://github.com/checkmarx-ts/CxAnalytix/tree/dev/various_improvements branch tonight with this issue (specifically this version which was the latest at the time of test https://github.com/checkmarx-ts/CxAnalytix/commit/7e3f98994819c6f71995f1c38eb8960f32f0fac0).

I think these changes have resolved this issue.

I tested with the same dataset (actually a small amount of more projects/scans i've created in this lab machine since opening the issue) I was able to load them all into MongoDB and the log files without any error.

With MongoDB Output 2 concurrent threads

PS C:\programdata\checkmarx\CxAnalytix\artifacts\Release> dotnet .\CxAnalytixCLI.dll
[2020-09-01 04:59:50,832]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-09-01 04:59:50,844]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\CxAnalytix\artifacts\Release
[2020-09-01 04:59:51,329]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-09-01 04:59:52,609]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 50 projects are targets to check for new scans. Since last scan: 0 projects removed, 50 new projects.
[2020-09-01 04:59:53,113]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 59 scans to check in 50 projects since 9/1/2020 4:59:51 AM.
[2020-09-01 05:01:44,824]  INFO [1] [CxAnalytixCLI.Program] (?:?) - End

With Log File Output 2 concurrent threads

PS C:\programdata\checkmarx\CxAnalytix\artifacts\Release> dotnet .\CxAnalytixCLI.dll
[2020-09-01 05:10:12,046]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-09-01 05:10:12,058]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\CxAnalytix\artifacts\Release
[2020-09-01 05:10:13,021]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 50 projects are targets to check for new scans. Since last scan: 0 projects removed, 50 new projects.
[2020-09-01 05:10:13,444]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 59 scans to check in 50 projects since 9/1/2020 5:10:12 AM.
[2020-09-01 05:11:43,415]  INFO [1] [CxAnalytixCLI.Program] (?:?) - End

With MongoDB and 10 concurrent threads

PS C:\programdata\checkmarx\CxAnalytix\artifacts\Release> dotnet .\CxAnalytixCLI.dll
[2020-09-01 05:13:38,016]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-09-01 05:13:38,030]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\CxAnalytix\artifacts\Release
[2020-09-01 05:13:38,391]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-09-01 05:13:39,541]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 50 projects are targets to check for new scans. Since last scan: 0 projects removed, 50 new projects.
[2020-09-01 05:13:39,959]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 59 scans to check in 50 projects since 9/1/2020 5:13:38 AM.
[2020-09-01 05:15:10,012]  INFO [1] [CxAnalytixCLI.Program] (?:?) - End

With MongoDB and 1 concurrent threads

PS C:\programdata\checkmarx\CxAnalytix\artifacts\Release> dotnet .\CxAnalytixCLI.dll
[2020-09-01 05:20:02,456]  INFO [1] [CxAnalytixCLI.Program] (?:?) - Start
[2020-09-01 05:20:02,468]  INFO [1] [CxAnalytixCLI.Program] (?:?) - CWD: C:\programdata\checkmarx\CxAnalytix\artifacts\Release
[2020-09-01 05:20:02,793]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - 2 calculated shard keys have been defined.
[2020-09-01 05:20:03,168]  WARN [1] [CxAnalytix.Out.MongoDBOutput.MongoDBOutFactory] (?:?) - Database CxAnalytix does not exist, it will be created.
[2020-09-01 05:20:03,184]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Detail
[2020-09-01 05:20:03,211]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SAST_Scan_Summary
[2020-09-01 05:20:03,221]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Summary
[2020-09-01 05:20:03,231]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_SCA_Scan_Detail
[2020-09-01 05:20:03,243]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Project_Info
[2020-09-01 05:20:03,254]  INFO [1] [CxAnalytix.Out.MongoDBOutput.MongoUtil] (?:?) - Creating collection RECORD_Policy_Violations
[2020-09-01 05:20:04,005]  INFO [1] [CxAnalytix.TransformLogic.ProjectResolver] (?:?) - 50 projects are targets to check for new scans. Since last scan: 0 projects removed, 50 new projects.
[2020-09-01 05:20:04,429]  INFO [1] [CxAnalytix.TransformLogic.ScanResolver] (?:?) - Resolved 59 scans to check in 50 projects since 9/1/2020 5:20:03 AM.
[2020-09-01 05:23:06,884]  INFO [1] [CxAnalytixCLI.Program] (?:?) - End

I'm testing on a c5.2xlarge in aws. Memory usage did not seem to exceed 100mb. CPU usage was high when I increased the concurrent thread count (expected). I think its unrelated to this issue but I took some screenshots of CPU just as reference point.

CPU Utilization w/ Mongo DB and 10 concurrent scans image

CPU Utilization w/ Mongo DB and 2 concurrent scans image