IRIS is a neurosymbolic framework that combines LLMs with static analysis for security vulnerability detection. IRIS uses LLMs to generate source and sink specifications and to filter false positive vulnerable paths.
- Workflow
- Dataset
- Environment Setup
- Quickstart
- Supported CWEs
- Supported Models
- Adding a CWE
- Contributing
- Citation
- Team
At a high level, IRIS takes a project and a CWE (vulnerability class, such as path traversal vulnerability or CWE-22) as input, statically analyzes the project, and outputs a set of potential vulnerabilities (of type CWE) in the project. To achieve this, IRIS takes the following steps:
- First we create CodeQL queries to collect external APIs in the project and all internal function parameters.
- We use an LLM to classify the external APIs as potential sources, sinks, or taint propagators. In another query, we use an LLM to classify the internal function parameters as potential sources. We call these taint specifications.
- Using the taint specifications from step 2, we build a project-specific and cwe-specific (e.g., for CWE 22) CodeQL query.
- Then we run the query to find vulnerabilities in the given project and post-process the results.
- We provide the LLM the post-processed results to filter out false positives and determine whether a CWE is detected.
We have curated a dataset of Java projects, containing 120 real-world previously known vulnerabilities across 4 popular vulnerability classes.
We support multiple ways to run IRIS:
First, clone the repository. We have included cwe-bench-java
as a submodule, so use the following command to clone correctly:
$ git clone https://github.com/iris-sast/iris --recursive
Installation Steps
Run scripts/setup_environment.sh
.
$ chmod +x scripts/setup_environment.sh
$ bash ./scripts/setup_environment.sh
This will do the following:
- creates a conda environment specified by environment.yml
- installs our patched version of CodeQL 2.15.3. This version of CodeQL is necessary for IRIS. To prevent confusion in case users already have an existing CodeQL version, we unzip this within the root of the iris directory. Then we add a PATH entry to the path of the patched CodeQL's binary.
- creates a directory to store CodeQL databases.
We have included CWE-Bench-Java as a submodule in IRIS in the data folder. We have also provided scripts to fetch and build Java projects to be used with IRIS.
For building, we need Java distributions as well as Maven and Gradle for package management. In case you have a different system than Linux x64, please modify data/cwe-bench-java/scripts/jdk_version.json
, data/cwe-bench-java/scripts/mvn_version.json
, and data/cwe-bench-java/scripts/gradle_version.json
to specify the corresponding JDK/MVN/Gradle files. In addition, please prepare 3 versions of JDK and put them under the java-env folder. Oracle requires an account to download the JDKs, and we are unable to provide an automated script. Download from the following URLs:
JDK 7u80: https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html
JDK 8u202: https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html
JDK 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
At this point, your java-env
directory should look like
- data/cwe-bench-java/java-env/
- jdk-7u80-linux-x64.tar.gz
- jdk-8u202-linux-x64.tar.gz
- jdk-17_linux-x64_bin.tar.gz
After this proceed to step 2 on fetching and building Java projects.
Now run the fetch and build script. You can also choose to fetch and not build, or specify a set of projects. You can find project names in the project_slug column in cwe-bench-java/data/build_info.csv
.
# fetch projects and build them
$ python3 data/cwe-bench-java/scripts/setup.py
# fetch projects and don't build them
$ python3 data/cwe-bench-java/scripts/setup.py --no-build
# example - build the perwendel__spark_CVE-2018-9159_2.7.1 project
$ python3 data/cwe-bench-java/scripts/setup.py --filter perwendel__spark_CVE-2018-9159_2.7.1
# example - only build projects under CWE-022 and CWE-078
$ python3 data/cwe-bench-java/scripts/setup.py --cwe CWE-022 CWE-078
# example - only build keycloak projects
$ python3 data/cwe-bench-java/scripts/setup.py --filter keycloak
# example - do not build any apache related projects
$ python3 data/cwe-bench-java/scripts/setup.py --exclude apache
This will create the build-info
and project-sources
directories. It will also install JDK, Maven, and Gradle versions used to build the projects in cwe-bench-java
. build-info
is used to store build information and project-sources
is where the fetched projects are stored.
To use CodeQL, you will need to generate a CodeQL database for each project. We have provided a script to automate this. The script will generate databases for all projects found in data/cwe-bench-java/project-sources
. To generate a database for a specific project, use the --project
argument.
# build CodeQL databases for all projects in project-sources
$ python3 scripts/build_codeql_dbs.py
# build a specific CodeQL database given the project slug
$ python3 scripts/build_codeql_dbs.py --project perwendel__spark_CVE-2018-9159_2.7.1
By running the provided scripts, you won't have to modify src/config.py
. Double check that the paths in the configuration are correct. Each path variable has a comment explaining its purpose.
Make sure you have followed all of the environment setup instructions before proceeding!
src/neusym_vul.py
is used to analyze one specific project. src/neusym_vul_for_query.py
is used to analyze multiple projects. Results are written to the output
directory.
See the Supported CWEs section for --query
arguments and the Supported Models section for --llm
arguments.
The following is an example of using IRIS to analyze perwendel__spark_CVE-2018-9159_2.7.1 for vulnerabilities that fall under CWE-022, using qwen2.5-coder-7b. Query cwe-022wLLM
refers to cwe-22 path traversal. You should be able to immediately execute this command to see an example of an evaluation.
$ python3 src/neusym_vul.py --query cwe-022wLLM --run-id <SOME_ID> --llm qwen2.5-coder-7b perwendel__spark_CVE-2018-9159_2.7.1
The following is an example of using IRIS to analyze zerotunaround for vulnerabilities that fall under CWE-022, using GPT-4. Query cwe-022wLLM
refers to cwe-22 path traversal.
$ python3 src/neusym_vul.py --query cwe-022wLLM --run-id <SOME_ID> --llm gpt-4 zeroturnaround__zt-zip_CVE-2018-1002201_1.12
After Step 4, IRIS will generate results.sarif
and results_pp.sarif
files in output/[project-name]/cwe-XXwLLM
containing the vulnerabilities found in the project before and after posthoc filtering. You can download Sarif Viewer to view the sarif files. Additionally, results.csv
contains the vulnerabilities in a simplified form.
Example Output directory structure (using run-id test1):
output
├── common
│ └── test1
│ └── cwe-022 (cache of common specs, can be reused across projects)
└── perwendel__spark_CVE-2018-9159_2.7.1
└── test1
├── common
│ ├── func_params.csv (list of all function parameters in the project)
│ ├── llm_labelled_source_func_params.json (function parameters labelled as sources by LLM)
│ ├── logs (Log files and raw LLM outputs)
│ │ └── label_func_params
│ │ ├── raw_llm_response_0.txt
│ │ ├── raw_llm_response_20.txt
│ │ ...
│ └── source_func_param_candidates.csv
├── cwe-022
│ ├── MySinks.qll (Codeql file listing all sink specifications returned by LLM)
│ ├── MySources.qll (Codeql file listing all source specifications returned by LLM)
│ ├── MySummaries.qll (Codeql file listing all summary specifications returned by LLM)
│ ├── Spec.yml (Alternate yml file listing all the specs)
│ ├── candidate_apis.csv (candidate specs)
│ ├── external_apis.csv
│ ├── llm_labelled_sink_apis.json (sinks labelled by LLM)
│ ├── llm_labelled_source_apis.json (sources labelled by LLM)
│ ├── llm_labelled_taint_prop_apis.json (taint propagators labelled by LLM)
│ └── logs (intermediate logs)
│ └── label_apis
│ ├── raw_llm_response_0.txt
│ ├── ...
│ ├── raw_user_prompt_0.txt
│ ├── ...
├── cwe-022wLLM (final results with all the vulnerabilities)
│ ├── results.csv
│ ├── results.sarif (before contextual filtering)
│ └── results_pp.sarif (after contextual filtering)
├── cwe-022wLLM-final
│ └── results.json (results statistics)
├── cwe-022wLLM-posthoc-filter (results of contextual filtering)
│ ├── logs
│ │ ├── raw_llm_response_0_0.txt
│ │ ├── raw_llm_response_0_1.txt
│ │ ├── ...
│ ├── results.json
│ ├── results.sarif
│ └── stats.json
├── fetch_* (intermediate analysis results)
│ ├── ...
└── log (Main log files)
├── ...
The easiest way to run IRIS on a Java project not in CWE-Bench-Java is to make the following changes:
- Add the project info to
data/cwe-bench-java/data/project_info.csv
. For instance, to run the latest perwendel/spark version:
ID,perwendel__spark_latest,,,,,perwendel,spark,latest,,,,
The only required fields are: project slug (use a unique name), github username, and github tag if any.
- Clone the project to
data/cwe-bench-java/project-sources
. Use the same folder name as the slug used above. - Add build info to
data/cwe-bench-java/data/build_info.csv
. For instance, you can add:perwendel__spark_latest,success,8u202,3.5.0,n/a,n/a
to use java 8 and mvn 3.5.0. Please use appropriate java/mvn/gradle versions as needed. - Build the Java project.
$ python3 data/cwe-bench-java/scripts/setup.py --filter [project slug]
- Generate the CodeQL database.
$ python3 scripts/build_codeql_dbs.py --project [project slug]
- Provide a list of internal packages in
data/cwe-bench-java/package-names/[slug].txt
. This should contain the package names of all internal packages of the project. E.g.,spark
forperwendel/spark
. The following command uses CodeQL to extract the internal packages and writes them to the required txt file in thepackage-names
directory. We provided a script to automate this.
$ python scripts/get_packages_codeql.py [project slug]
The dockerfile has scripts that will create the conda environment, clones cwe-bench-java
, and installs the patched CodeQL version. Before building the dockerfile you will need download the JDK versions needed. Then the dockerfile copies them to the container.
For building, we need Java distributions as well as Maven and Gradle for package management. In addition, please prepare 3 versions of JDK and put them in the iris root directory. Oracle requires an account to download the JDKs, and we are unable to provide an automated script. Download from the following URLs:
JDK 7u80: https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html
JDK 8u202: https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html
JDK 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
At this point, your iris
directory should look like
- /iris
- jdk-7u80-linux-x64.tar.gz
- jdk-8u202-linux-x64.tar.gz
- jdk-17_linux-x64_bin.tar.gz
Now, build and run the docker container.
# build
$ docker build -t iris .
# run
$ docker run -it iris
# run with all GPUs
$ docker run --gpus all -it iris
# run with specific GPUs
$ docker run --gpus '"device=0,1"' -it iris
Confirm that the patched CodeQL is in your PATH.
After this, proceed to step 2 on fetching and building Java projects.
Mac: If you have a Mac, you can also run IRIS. You must separately install java libraries using the dmg files provided by oracle (using the same links mentioned here). Please specify the appropriate Java directories in data/cwe-bench-java/scripts/jdk_version.json
. Alternatively, you can use the provided dockerfile for setup.
Windows: We have not evaluated IRIS on windows machines. If you are interested in extending IRIS's support to windows machines, please feel free to raise a PR.
Here are the following CWEs supported, that you can specify as an argument to --query
when using src/neusym_vul.py
and src/neusym_vul_for_query.py
.
cwe-022wLLM
- CWE-022 (Path Traversal)cwe-078wLLM
- CWE-078 (OS Command Injection)cwe-079wLLM
- CWE-079 (Cross-Site Scripting)cwe-094wLLM
- CWE-094 (Code Injection)
We support the following models with our models API wrapper (found in src/models
) in the project. Listed below are the arguments you can use for --llm
when using src/neusym_vul.py
and src/neusym_vul_for_query.py
. You're free to use your own way of instantiating models or adding on to the existing library. Some of them require your own API key or license agreement on HuggingFace.
List of Models
codegen-16b-multi
codegen25-7b-instruct
codegen25-7b-multi
codellama-70b-instruct
codellama-34b
codellama-34b-python
codellama-34b-instruct
codellama-13b-instruct
codellama-7b-instruct
codet5p-16b-instruct
codet5p-16b
codet5p-6b
codet5p-2b
deepseekcoder-33b
deepseekcoder-7b
deepseekcoder-v2-15b
gemini-1.5-pro
gemini-1.5-flash
gemini-pro
gemini-pro-vision
gemini-1.0-pro-vision
gemma-7b
gemma-7b-it
gemma-2b
gemma-2b-it
codegemma-7b-it
gemma-2-27b
gemma-2-9b
gpt-4
gpt-3.5
gpt-4-1106
gpt-4-0613
llama-2-7b-chat
llama-2-13b-chat
llama-2-70b-chat
llama-2-7b
llama-2-13b
llama-2-70b
llama-3-8b
llama-3.1-8b
llama-3-70b
llama-3.1-70b
llama-3-70b-tai
mistral-7b-instruct
mixtral-8x7b-instruct
mixtral-8x7b
mixtral-8x22b
mistral-codestral-22b
qwen2.5-coder-7b
qwen2.5-coder-1.5b
qwen2.5-14b
qwen2.5-32b
qwen2.5-72b
starcoder
starcoder2-15b
wizardcoder-15b
wizardcoder-34b-python
wizardcoder-13b-python
wizardlm-70b
wizardlm-13b
wizardlm-30b
Coming soon!
Feel free to address any open issues or add your own issue and fix. We love feedback! Please adhere to the following guidelines.
- Create a Github issue outlining the piece of work. Solicit feedback from anyone who has recently contributed to the component of the repository you plan to contribute to.
- Checkout a branch from
main
- preferably name your branch[github username]/[brief description of contribution]
- Create a pull request that refers to the created github issue in the commit message.
- To link to the github issue, in your commit for example you would simply add in the commit message: [what the PR does briefly] #[commit issue]
- Then when you push your commit and create your pull request, Github will automatically link the commit back to the issue. Add more details in the pull request, and request reviewers from anyone who has recently modified related code.
- After 1 approval, merge your pull request.
Consider citing our paper:
@inproceedings{li2025iris,
title={LLM-Assisted Static Analysis for Detecting Security Vulnerabilities},
author={Ziyang Li and Saikat Dutta and Mayur Naik},
booktitle={International Conference on Learning Representations},
year={2025},
url={https://arxiv.org/abs/2405.17238}
}
IRIS is a collaborative effort between researchers at the University of Pennsylvania and Cornell University. Please reach out to us if you have questions about IRIS.

