Skip to content

Commit 210a462

Browse files
authored
Merge pull request diffblue#540 from diffblue/smowton/feature/gitlab-integration-prototype
Add initial prototype of Gitlab integration scripts
2 parents e829d10 + ecb8c65 commit 210a462

11 files changed

+992
-0
lines changed

gitlab-integration/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.js
2+
*.js.map
3+
node_modules
4+

gitlab-integration/README

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Steps to set up Gitlab security analysis:
2+
3+
All steps are performed on the same machine, which will run the Diffblue platform
4+
and the Gitlab runner.
5+
6+
1. Set up an instance of Diffblue platform capable of running security-analyser.
7+
Check it is working by manually creating a project and running an analysis
8+
on a test project, such as github.com/smowton/security-demo.git
9+
10+
2. Create a user named 'diffblue' with password 'password'
11+
12+
3. Install Node.js and npm
13+
14+
4. Install dependencies and compile the integration script and platform API
15+
bindings: in the same directory as this README, run:
16+
$ npm install
17+
$ npm run build
18+
19+
5. Install the Gitlab runner on this machine:
20+
https://docs.gitlab.com/runner/install/
21+
22+
6. Register the runner:
23+
https://docs.gitlab.com/runner/register/
24+
25+
Note that guide shows registering the runner as a system service, but running
26+
it as an ordinary user is fine for our purposes. When asked for a runner
27+
executor, choose 'shell'. When asked for tags, enter 'diffblue'.
28+
29+
7. Start the runner (in a scratch working directory):
30+
$ gitlab-runner run
31+
32+
8. Add a 'sast' job to your Gitlab repository's .gitlab-ci.yml file. A minimum
33+
working example is included in this directory, named gitlab-ci.yml.example.
34+
Replace the dummy /absolute/path/to/gitlab-wrapper.sh with the absolute path
35+
of this directory.
36+
37+
Note the 'tags' section is unnecessary if this is the only runner registered
38+
for CI jobs for this repository, but is important if you will be (for example)
39+
using the normal Gitlab.com shared runners for normal CI jobs.
40+
41+
9. Test: create a Gitlab merge request and you should see a security report
42+
displayed after the 'sast' job has completed running security analysis.
43+
Note Gitlab Ultimate or Gold is required for this to work -- a free short-
44+
term trial can be used for testing: https://about.gitlab.com/free-trial/

gitlab-integration/analyse-project.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import * as models from "./models";
2+
import * as platform from "./api";
3+
import { wait } from "./misc";
4+
import { TwoColumnLogger } from "./logger";
5+
import fs = require("fs");
6+
7+
if(process.argv.length < 4 || process.argv.length > 5) {
8+
console.error("Usage: analyse-project.ts https://somehub.com/user/repo.git branchname [sast-report.json]");
9+
process.exit(1);
10+
}
11+
12+
async function securityAnalysis() {
13+
14+
const projectName = `gitlab-${Date.now()}`;
15+
let localMachine: models.Instance = {
16+
name: "local-executor",
17+
ip: "localhost",
18+
log: new TwoColumnLogger("local-executor"),
19+
project: {
20+
name: projectName,
21+
fullName: "not-needed",
22+
uri: process.argv[2],
23+
branch: process.argv[3],
24+
manualVerify: { verifyBranch: "x", innerDir: "y", jacocoFile: "z" }
25+
},
26+
status: "USER_CREATED",
27+
type: "notype",
28+
zones: [],
29+
zone: "nozone",
30+
zoneIndex: 0,
31+
diskImg: { name: "nodiskimgname", link: "nodiskimglink" },
32+
username: "diffblue",
33+
duration: { start: "nodurationstart" },
34+
};
35+
36+
let startTime = Date.now();
37+
38+
localMachine = await platform.createProject(localMachine);
39+
localMachine = await platform.initialiseProject(localMachine);
40+
localMachine = await platform.startAnalysis(localMachine);
41+
42+
do {
43+
localMachine = await platform.getAnalysisProgress(localMachine);
44+
if (localMachine.analysisStatus === "RUNNING" || localMachine.analysisStatus === "WAITING") {
45+
let elapsed = Date.now() - startTime;
46+
await wait(elapsed / 10000); // Wait for 10% of time elapsed so far
47+
}
48+
} while (localMachine.analysisStatus === "RUNNING" || localMachine.analysisStatus === "WAITING");
49+
50+
let issues = await platform.getIssues(localMachine);
51+
52+
localMachine.log.debug(`Identified ${issues.length} issues`);
53+
localMachine.log.debug(JSON.stringify(issues));
54+
55+
if(process.argv.length == 5) {
56+
57+
let report = issues.map(
58+
function(issue : any) {
59+
60+
// TODO: query the platform's public-facing URL
61+
let testUrl = `http://localhost/${projectName}/${localMachine.analysisNum}/tests/${issue.id}/trace`;
62+
63+
return {
64+
file: `${issue.testClassDir}/${issue.testClass}`,
65+
message: issue.testName,
66+
priority: "High",
67+
tool: "Diffblue-security",
68+
url: testUrl,
69+
cve: `Click here ${testUrl}`
70+
//cve: testUrl // Mandatory key
71+
};
72+
}
73+
);
74+
75+
localMachine.log.debug(`Writing issue report to ${process.argv[4]}`);
76+
fs.writeFileSync(process.argv[4], JSON.stringify(report));
77+
78+
}
79+
80+
process.exit(issues.length == 0 ? 0 : 2);
81+
}
82+
83+
securityAnalysis();

0 commit comments

Comments
 (0)