MobSF (Mobile Security Framework) is an automated mobile penetration testing framework. You upload a build to it, and it informs you of security issues that it finds. There's a great tutorial on how to run it in CI, but the script it uses is in Ruby. If you would rather run it in CircleCI build steps directly, this article will show you how.

MobSF has a docker image. However, it lacks certain crucial tools, like Git, so I opted to use a CircleCI machine build and run the docker image on it.

To get the MobSF docker image, run docker pull opensecurity/mobile-security-framework-mobsf.

MobSF requires an API key to authenticate calls to its APIs. The MobSF API docs say "You can pre-configure the API key by setting the environment variable MOBSF_API_KEY." However, since MobSF is on a Docker container and we are running a machine build, you can't set the environment variable on the CircleCI machine. Instead, you can create an environment variables file, then pass it to the Docker container. To create the file, run a command like echo "MOBSF_API_KEY=$MOBSF_API_KEY" > env.list. You can generate an API key however you wish, then store it as a CircleCI environment variable and reference it in the build script, instead of pasting it directly, which is insecure.

Then to actually run MobSF, run the command docker run -it --env-file ./env.list -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest and pass the environment variables file to it with the --env-file flag.

I'll give some examples of how I've used the MobSF APIs. Naturally, we would want to upload and scan a build. To upload, you can do something like:

sleep 30s
response=`curl -F 'file=@./my-build.apk' http://localhost:8000/api/v1/upload -H "Authorization:$MOBSF_API_KEY"`
SCAN_TYPE=`echo $response | jq '.scan_type' | sed 's/"//g'`
FILE_NAME=`echo $response | jq '.file_name' | sed 's/"//g'`
HASH=`echo $response | jq '.hash' | sed 's/"//g'`
echo "export SCAN_TYPE=$SCAN_TYPE" >> $BASH_ENV
echo "export FILE_NAME=$FILE_NAME" >> $BASH_ENV
echo "export HASH=$HASH" >> $BASH_ENV

Explaining the commands: the sleep step is to make sure the Docker container has finished starting. And once the upload is finished, we want to parse the results somehow to use it in subsequent steps. Since the response is in json, we can use a parser like jq, which you will need to install in CircleCI. You can install it by running sudo apt-get install jq. Once we have the values we want, we need to pass it to $BASH_ENV to persist them to the next step, as each CircleCI step uses a new shell.

To scan our build, we can run:

response=`curl -X POST --url http://localhost:8000/api/v1/scan --data "scan_type=$SCAN_TYPE&file_name=$FILE_NAME&hash=$HASH" -H "Authorization:$MOBSF_API_KEY"`
echo $response >> report.json

Then we can parse our report with OWASP Glue by running:

docker run -it -v $(pwd):/app owasp/glue:raw-latest ruby bin/glue -t Dynamic -T /app/report.json --mapping-file mobsf --finding-file-path /app/android.json

See the OWASP Glue docs on ignoring duplicated findings with the --finding-file-path flag. On the first run, OWASP Glue will generate this file, and you can subsequently supply it yourself.