diff --git a/docs/Configuration.md b/docs/Configuration.md
index ea668f321..ebfeb11fb 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -182,7 +182,8 @@ gitlab:
bitbucket:
webhook-token: XXXXX
token: XXXXX
- url: https://api.bitbucket.org
+ url: https://bitbucket.org
+ api-url: https://api.bitbucket.org
api-path: /2.0
false-positive-label: false-positive
@@ -911,9 +912,10 @@ azure:
### Bitbucket (Cloud and Server)
```yaml
bitbucket:
- webhook-token
+ webhook-token: xxx
token: :xxx
- url: http://api.bitbucket.org
+ url: http://bitbucket.org
+ api-url: http://api.bitbucket.org
api-path: /2.0
```
@@ -921,7 +923,8 @@ bitbucket:
|--------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `webhook-token` | | Token used as a shared secret when calling the CxFlow WebHook WebService. It authenticates users for the request. The Bitbucket cloud does not allow for a shared secret, therefore a URL parameter called token, must be provided in this case. |
| `token` | | This is the API token with access to the repository with at least Read only access to code and the ability to add comments to pull requests. BitBucket requires the **:** format in the configuration.
`userid:app password`(Format while using BitBucket Cloud)
`userid:password`(Format while using BitBucket Server) |
-| `url` | | - [https://api.bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://api.companyxyzbitbucket](https://api.companyxyzbitbucket) (URL for the BitBucket server is just the server hostname with `api.` prefixed) |
+| `api-url` | | - [https://api.bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://api.companyxyzbitbucket](https://api.companyxyzbitbucket) (URL for the BitBucket server is just the server hostname with `api.` prefixed) |
+| `url` | | - [https://bitbucket.org](https://api.bitbucket.org) (URL for the Cloud BitBucket)
- [https://companyxyzbitbucket](https://api.companyxyzbitbucket)(URL for the BitBucket server is just the server hostname) |
| `api-path` | | The API URL path (appended to the URL) for BitBucket |
| 'scan-submitted-comment` | true | Comment on Merge Request with "Scan submitted (or not submitted) to Checkmarx ...". |
diff --git a/src/main/java/com/checkmarx/flow/CxFlowRunner.java b/src/main/java/com/checkmarx/flow/CxFlowRunner.java
index e7e452506..546ab446f 100644
--- a/src/main/java/com/checkmarx/flow/CxFlowRunner.java
+++ b/src/main/java/com/checkmarx/flow/CxFlowRunner.java
@@ -62,6 +62,7 @@ public class CxFlowRunner implements ApplicationRunner {
private final FlowProperties flowProperties;
private final CxScannerService cxScannerService;
private final JiraProperties jiraProperties;
+ private final BitBucketProperties bitBucketProperties;
private final GitHubProperties gitHubProperties;
private final GitLabProperties gitLabProperties;
private final IastService iastService;
@@ -490,7 +491,20 @@ else if (args.containsOption("gitlab") && !ScanUtils.anyEmpty(namespace, repoNam
gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP_OAUTH2.concat(token).concat("@"));
scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.GITLAB, args);
} else if (args.containsOption("bitbucket") && containsRepoArgs(namespace, repoName, branch)) {
- log.warn("Bitbucket git clone scan not implemented");
+
+ repoUrl = getNonEmptyRepoUrl(namespace, repoName, repoUrl, bitBucketProperties.getGitUri(namespace, repoName));
+ String token = bitBucketProperties.getToken();
+ gitAuthUrl = repoUrl.replace(Constants.HTTPS, Constants.HTTPS.concat(token).concat("@"));
+ gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@"));
+
+ scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.BITBUCKET, args);
+ } else if (args.containsOption("bitbucket-server") && containsRepoArgs(namespace, repoName, branch)) {
+ repoUrl = getNonEmptyRepoUrl(namespace, repoName, repoUrl, bitBucketProperties.getGitUri(namespace, repoName));
+ String token = bitBucketProperties.getToken();
+ gitAuthUrl = repoUrl.replace(Constants.HTTPS, Constants.HTTPS.concat(token).concat("@"));
+ gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@"));
+
+ scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.BITBUCKETSERVER, args);
} else if (args.containsOption("ado") && containsRepoArgs(namespace, repoName, branch)) {
if (!args.containsOption(IAST_OPTION)) {
if(adoProperties.getProjectName().isEmpty()){
@@ -503,6 +517,7 @@ else if (args.containsOption("gitlab") && !ScanUtils.anyEmpty(namespace, repoNam
gitAuthUrl = gitAuthUrl.replace(Constants.HTTP, Constants.HTTP.concat(token).concat("@"));
scanRemoteRepo(request, repoUrl, gitAuthUrl, branch, ScanRequest.Repository.ADO, args);
}
+
}
} else if (file != null) {
scanLocalPath(request, file);
diff --git a/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java b/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java
index d79ac1536..c601146df 100644
--- a/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java
+++ b/src/main/java/com/checkmarx/flow/config/BitBucketProperties.java
@@ -28,4 +28,9 @@ public void setApiPath(String apiPath) {
public void setIpAddresses(List ipAddresses) {
this.ipAddresses = ipAddresses;
}
+
+ public String getGitUri(String namespace, String repoName) {
+ String format = "%s/%s/%s.git";
+ return String.format(format, getUrl(), namespace, repoName);
+ }
}
diff --git a/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java b/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java
index b1f13721b..1a43f539d 100644
--- a/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java
+++ b/src/test/java/com/checkmarx/flow/cucumber/component/batch/BatchComponentSteps.java
@@ -51,7 +51,7 @@ public class BatchComponentSteps {
private final ThresholdValidator thresholdValidator;
private final BuildProperties buildProperties;
private final PDFProperties pdfProperties;
-
+ private final BitBucketProperties bitBucketProperties;
private CxFlowRunner cxFlowRunner;
private String projectName;
private String teamName;
@@ -71,6 +71,7 @@ public void sastClientIsMocked() throws CheckmarxException {
cxFlowRunner = new CxFlowRunner(flowProperties,
cxScannerService,
jiraProperties,
+ bitBucketProperties,
gitHubProperties,
gitLabProperties,
iastService,
diff --git a/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java b/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java
index 86057bd39..0f07126c3 100644
--- a/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java
+++ b/src/test/java/com/checkmarx/flow/cucumber/integration/cli/iast/IastCliSteps.java
@@ -105,6 +105,7 @@ public class IastCliSteps {
private final List scanners;
private final ThresholdValidator thresholdValidator;
private final PDFProperties pdfProperties;
+ private final BitBucketProperties bitBucketProperties;
private String urlRequest;
private HttpHeaders headers;
@@ -120,6 +121,7 @@ public void mockCliRunner(String scanTag, String bugTracker, String params) {
flowProperties,
cxScannerService,
jiraProperties,
+ bitBucketProperties,
gitHubProperties,
gitLabProperties,
iastService,