You can configure a regular security analysis of your APEX applications using GitLab.
The examples here all use a private repository on GitLab.com: https://gitlab.com/recxtim/apexsectest
Do not use this guide on a public repository because your licensed version of ApexSec and the vulnerability scan results will all be accessible to everyone.
To start, create a new GitLab project and commit the following files:
- A copy of ApexSec:
apexsec-linux64.jar
- Your APEX application and supporting PL/SQL schema, packages, procedures etc. (here, we’re using
BigBadBlog.sql
our demonstration vulnerable application) - The following
.gitlab-ci.yml
file:
stages:
- analysis
run-apexsec:
stage: analysis
image: openjdk:17
script:
- mkdir -p apexsec-results
- java -jar apexsec-linux64.jar --file src/ --report-csv apexsec-results/output.apexsec
allow_failure: true
artifacts:
when: always
paths:
- apexsec-results/
only:
- main
This pipeline will run on commit/push to main. Using allow_failure
means the pipeline will produce warnings, not failures.
When committed, the pipeline executes:

The job failed because ApexSec returned a non-zero error code, indicating that vulnerabilities were identified.
The output from ApexSec is stored in an artifact:

Download artifacts.zip
$ unzip -t artifacts.zip
Archive: artifacts.zip
testing: apexsec-results/ OK
testing: apexsec-results/output.apexsec OK
testing: apexsec-results/output.csv OK
This is a simple way to integrate ApexSec with your GitLab development life cycle.
Check the results by vulnerability class
Check the results by vulnerability class
Now, let’s create a more complex example that passes/fails separate stages based on specific result vulnerability classes.
Update the .gitlab-ci.yml
file
stages:
- analysis
- checksql
- checkpotentialsql
run-apexsec:
stage: analysis
image: openjdk:17
script:
- mkdir -p apexsec-results
- java -jar apexsec-linux64.jar --file src/ --report-csv apexsec-results/output.apexsec
allow_failure: true
artifacts:
when: always
paths:
- apexsec-results/
only:
- main
check-results-sql:
stage: checksql
dependencies:
- run-apexsec
script:
- echo "Checking SQL Injection"
- if grep "^SQL Injection" apexsec-results/output.csv; then exit 1; else exit 0; fi
allow_failure: true
check-results-potential-sql:
stage: checkpotentialsql
dependencies:
- run-apexsec
script:
- echo "Checking Potential SQL Injection"
- if grep "^Potential SQL Injection" apexsec-results/output.csv; then exit 1; else exit 0; fi
allow_failure: true
This executes on commit:

This shows there were SQL Injection vulnerabilities (checksql has warnings), but no Potential SQL Injection issues (checkpotentialsql passed).
Commit the project
Using the following configuration we can push the ApexSec output back into the git repository. The ApexSec command line parameters have been modified to also output the JUnit XML file.
This output format will suppress issues that have been marked as false positive within the ApexSec project. The check stages now process this JUnit XML.
Update the .gitlab-ci.yml
:
stages:
- analysis
- commitproject
- checksql
- checkpotentialsql
run-apexsec:
stage: analysis
image: openjdk:17
script:
- mkdir -p apexsec-results
- java -jar apexsec-linux64.jar --file src/ --report-csv --junit apexsec-results/output.apexsec
allow_failure: true
artifacts:
when: always
paths:
- apexsec-results/
only:
- main
commit-project:
stage: commitproject
script:
- git config --global user.email "<your email>"
- git config --global user.name "<your name>"
- git checkout ${CI_COMMIT_REF_NAME}
- git add apexsec-results/output.apexsec apexsec-results/output.csv
- git commit -m "apexsec results"
- git push -o ci.skip "https://${GITLAB_USER_NAME}:${GIT_PUSH_TOKEN}@${CI_REPOSITORY_URL#*@}"
check-results-sql:
stage: checksql
dependencies:
- run-apexsec
script:
- echo "Checking SQL Injection"
- grep 'name="SQL Injection".*failures="0"' apexsec-results/output.junit.xml
allow_failure: true
check-results-potential-sql:
stage: checkpotentialsql
dependencies:
- run-apexsec
script:
- echo "Checking Potential SQL Injection"
- grep 'name="Potential SQL Injection".*failures="0"' apexsec-results/output.junit.xml
allow_failure: true
To be able to push to the repository, the pipeline needs a token. Configure this in Preferences, Access Token as “GIT_PUSH_TOKEN”:

In GitLab configure the variables in Settings, CI/CD:

Now when the pipeline runs the results from ApexSec are committed to the repository in apexsec-results.
We can then open this project file in ApexSec Desktop, review the results, and mark issues as false positives.
(For more information see: https://apexsec.recx.co.uk/apexsec-3-usage-guides/usage-guides/opening-an-existing-project/)
The project can be saved and pushed back to the repository so that the next execution of the GitLab pipeline will use the project that contains the marked false positives. These are suppressed in the JUnit output and the pipeline output stages will then succeed if vulnerabilities were found, but they were marked as false positives.
To demonstrate, we mark all SQL Injection issue as false positives (we do not recommend you do this in a real-world scenario!):

Now when the pipeline runs, the check-results-sql passes:

Summary
We’ve shown how to integrate ApexSec into your GitLab CI/CD processes by using a pipeline that executes when the main branch changes. A simple example was provided that runs ApexSec and saves the results to GitLab artifacts. Then this was extended to process the output as separate pipeline stages, to indicate the success or failure of the vulnerability scan on specific classes of vulnerability.
Then a complete end-to-end workflow was demonstrated:
- ApexSec runs on commit
- The ApexSec project file and JUnit output is saved to the repository
- User’s can pull the repository, then open the project in ApexSec to review results, make comments and mark false positives
- The project can be pushed back to the repository along with any APEX application changes
- ApexSec then runs again, using this update project and APEX application
- Separate stages indicate vulnerabilities are present for specific vulnerability classes