├── .gitattributes
├── .github
└── workflows
│ └── docker-build.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── SECURITY.md
├── acr
├── README.md
└── docker-compose.yml
├── analyzers
├── custom-semgrep
│ ├── LICENSE
│ └── rules
│ │ └── custom
│ │ ├── custom.yaml
│ │ ├── detected-log4j-core.xml
│ │ ├── detected-log4j-core.yaml
│ │ ├── log4j-message-injection.java
│ │ ├── log4j-message-injection.yaml
│ │ └── spring-controller-exists.yaml
├── eslint.yml
├── find_sec_bugs.yml
├── find_unicode_control2.py
└── json_reporter.js
├── cli-html.sh
├── cli.sh
├── data
└── .empty
└── docker
└── docker
└── worker-cli
└── Dockerfile
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css linguist-detectable=false
2 | *.js linguist-detectable=false
3 | *.es6 linguist-detectable=false
4 | *.jsx linguist-detectable=false
5 | *.scss linguist-detectable=false
6 | *.yar linguist-detectable=false
7 |
--------------------------------------------------------------------------------
/.github/workflows/docker-build.yml:
--------------------------------------------------------------------------------
1 | name: Build and Push Docker Images
2 |
3 | permissions:
4 | id-token: write
5 | contents: read
6 | attestations: write
7 | packages: write
8 |
9 | on:
10 | push:
11 | branches:
12 | - main
13 | pull_request:
14 | branches:
15 | - main
16 |
17 | jobs:
18 | build:
19 | runs-on: ubuntu-latest
20 | strategy:
21 | matrix:
22 |
23 | service: [worker-cli]
24 | include:
25 | - service: worker-cli
26 | dockerfile: docker/docker/worker-cli/Dockerfile
27 | context: docker/docker/worker-cli
28 | component: worker-cli
29 |
30 |
31 | env:
32 | REGISTRY: docker.io
33 | IMAGE_NAME: tcosolutions/betterscan-${{ matrix.component }}
34 |
35 | steps:
36 | - name: Checkout code
37 | uses: actions/checkout@v4
38 |
39 | - name: Set up Docker Buildx
40 | uses: docker/setup-buildx-action@v3
41 |
42 | - name: Login to Docker Hub
43 | uses: docker/login-action@v3
44 | with:
45 | username: ${{ secrets.DOCKERHUB_USERNAME }}
46 | password: ${{ secrets.DOCKERHUB_TOKEN }}
47 |
48 | - name: Build and push Docker image
49 | id: build-push
50 | uses: docker/build-push-action@v6
51 | with:
52 | context: ${{ matrix.context }}
53 | file: ${{ matrix.dockerfile }}
54 | platforms: linux/amd64, linux/arm64
55 | push: true
56 | tags: |
57 | ${{ env.IMAGE_NAME }}:latest
58 | ${{ env.IMAGE_NAME }}:${{ github.sha }}
59 |
60 | - name: Generate artifact attestation
61 | uses: actions/attest-build-provenance@v1
62 | with:
63 | subject-name: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/betterscan-${{ matrix.component }}
64 | subject-digest: ${{ steps.build-push.outputs.digest }}
65 | push-to-registry: true
66 | env:
67 | DOCKER_HUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
68 | DOCKER_HUB_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 | *.pyc
3 | *~
4 | **sass-cache**
5 | celerybeat-schedule
6 | .merge_file*
7 | **/lastBuild/*
8 | *BASE*
9 | *ORIG*
10 | *BACKUP*
11 | *LOCAL*
12 | *REMOTE*
13 | *\#
14 | **/settings/common.yml
15 | **/venv*/
16 | .checkmate/*
17 | *.db
18 | *.orig
19 | **/.cache/*
20 | **/secrets.yml
21 | .DS_Store
22 | run.sh
23 | .idea
24 | **/settings.yml
25 | node_modules/*
26 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | Betterscan's Project Stewards (marcinguy@gmail.com).
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | Open DevSecOps Orchestration Toolchain
10 |
11 |
12 | ## License
13 |
14 | Released under [AGPL-3.0](/LICENSE) by [@tcosolutions](https://github.com/tcosolutions).
15 |
16 | Scan your source code and infra IaC against top **security** risks
17 |
18 |
19 |
20 | ## Overview
21 |
22 | **Betterscan** is a state-of-the-art orchestration toolchain designed to scan your source code and Infrastructure as Code (IaC) for **security** and **compliance** risks.
23 |
24 | ## Open and Developer friendly DevSecOps toolchain
25 |
26 | Betterscan uses many tools for Code, Cloud, secrets. All the best Tools, researched, setup, ran together, unifed and de-duplicated results, **so you don't have to do it**. Added our own checkers also. Continuous Security. Fit for purpose and results.
27 |
28 | Betterscan is performing security reviews of codebases using graph analysis. It utilizes Neo4j and Fast GraphRAG to query and visualize relationships within the code, helping identify potential security risks and vulnerabilities by analyzing the structure and flow of the code (using AI capabilities for this). Done via `aigraphcodescan` plugin.
29 |
30 |
31 | ## License Information
32 |
33 | ## Debian Base Image
34 |
35 | Docker images includes software from the Debian GNU/Linux distribution. Debian is made available under various open-source licenses. See below for details:
36 |
37 | The full text of the licenses for software included in Debian can be found in /usr/share/common-licenses/ within the Debian system.
38 |
39 | ## Additional Software Licenses
40 |
41 | Docker images includes software licensed under various licenses. The full license texts can be found in the image at `/srv/betterscan/LICENSE`.
42 |
43 | If you want to scan your Code and Infrastructure (including Secrets, SBOMs, and dependencies)
44 |
45 | Below setup is for Linux (Ubuntu), you can also run it on MacOS/Docker and Windows via WSL/Docker.
46 |
47 |
48 |
49 | # Quickstart
50 |
51 |
52 |
53 | ## **2 options** are available:
54 |
55 | ### 1. Binary runtime
56 |
57 | Scripts used checkmate CLI binary (python based)
58 |
59 | Below are the checkmate current parameters:
60 |
61 | Explanation of Parameters
62 |
63 | ```--backend:```
64 |
65 | Specifies the backend type.
66 |
67 | Choices: "sql" (default), "sqlite".
68 |
69 | Example: --backend sql
70 |
71 | ```--backend-opts:```
72 |
73 | Provides backend-specific options, such as the connection string for an SQL database or file path for SQLite.
74 |
75 | Example for SQL: --backend-opts "postgresql://user:password@localhost/mydatabase"
76 |
77 | Example for SQLite: --backend-opts "sqlite:///path/to/database.db"
78 |
79 | defaults to memory store if not set for SQLite
80 |
81 | ```--path:```
82 |
83 | Specifies the path to create the new project. Defaults to the current working directory if not specified.
84 |
85 | Example: --path "/path/to/project"
86 |
87 | ```--pk:```
88 |
89 | Sets the primary key for the project. If not provided, a UUID is generated.
90 |
91 | Example: --pk "my_custom_primary_key"
92 |
93 | Example Usage
94 |
95 | To create a project with a SQL backend and a specific connection string:
96 |
97 | ```checkmate --backend sql --backend-opts "postgresql://user:password@localhost/mydatabase" --path "/path/to/project" --pk "custom_pk"```
98 |
99 |
100 |
101 | #### CLI output
102 |
103 | Run in command prompt in your Git repository folder:
104 |
105 | `sh <(curl https://raw.githubusercontent.com/tcosolutions/betterscan/main/cli.sh)`
106 |
107 | ### HTML, JSON, SARIF output
108 |
109 | The result will be in the current directory in "report.html", "report.json" and "report.sarif" file
110 |
111 | Run in command prompt in your Git repository folder:
112 |
113 | `sh <(curl https://raw.githubusercontent.com/tcosolutions/betterscan/main/cli-html.sh)`
114 |
115 |
116 | That's it.
117 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 |
6 | Please report (suspected) security vulnerabilities to marcinguy@gmail.com. You will receive a response from us within 48 hours. If the issue is confirmed, we will release a patch as soon as possible depending on complexity, but historically within a few days.
7 |
8 | Using the gpg
9 |
10 | ```
11 | Key ID
12 | E8958CBEF5CD8AC6
13 | PGP Fingerprint
14 | CF7D CDAE D1F7 E8B3 1990 91E8 E895 8CBE F5CD 8AC6
15 |
16 |
17 | -----BEGIN PGP PUBLIC KEY BLOCK-----
18 |
19 | xsFNBGBDOGkBEAD59ZOkvlfyIrXg8sIfvhq8lG6CLX0Q4WsxBCaqtSdNBume
20 | Lph+MRsbI8szzM2DTaI6vkYKPv276ALJU3GtZGF1MaM+SbPrHv4I7sMIhLTh
21 | aGUgyECTGqSA2KiDAD0whjaFWUteWQJ55hD/HFAjmj+IX6ubB/EnYS5MhRuA
22 | vBL5Ih5w/kE3W4OQz/YGUaqa1aOSoTH767R8nPRYI9KQuxLNs7+ttRsQjfRo
23 | 4nMuGbTKUJGr7vYrXnMxMRVG5wGveosBtfYF9c4iKuvvG5Xhcp226qE4I0bs
24 | N3tp6Wh1baj7v3QJsKYKWs3WAfbsprAd3MMv+Hq6GeVrFLEwNLJBu4SdiF+m
25 | Sp8Z/QfUGkbbzs0gMSQxrUW7ML63VLHS95gGeKsY3014MCq9DiKlRw7TUTtj
26 | if3w0nFT+6j4z+nB5PwL6NuX3FW6hADQxj6APQh3JxJm4CvDa4BFf8RvFgxy
27 | icfgC6rItMusz3sqzYfFEuwX3/6NJ1YWSWWmkks5tQNhR281OokRV9Nj8nKd
28 | L9bEjXibFGBhZUgyVbbuVxeytDBQ22SRBhkhAqqy/25LBMcsl1p3CH1UaiQr
29 | +qU380l76/n/NI8vtTsEp8QiUxj4s5GpNkA6C1Tt3snaLQsEGgmb66f3Jxgv
30 | X5rHoSh1zCIj7/105ecK5dSR4WQGZNe6jfpzMQARAQABzSZNYXJjaW4gS296
31 | bG93c2tpIDxtYXJjaW5ndXlAZ21haWwuY29tPsLBdQQQAQgAHwUCYEM4aQYL
32 | CQcIAwIEFQgKAgMWAgECGQECGwMCHgEACgkQ6JWMvvXNisbW4g//fmDFwQiY
33 | VQgEaoD1/orz6J2Rqa25YEd08rw+N7ztF8HSAIL+p4nbJ7piMIh6L6+px259
34 | tgCK2Zg1RU7qDV6Y7lfFXQK+Huj2ss6/rKXWhwb+LM+heqzhiaH40ierz3EC
35 | 88DEtVqR6D5TgP36KT+vrumXPsptqH4GydGq6k2zRKs6V67ExhcoQVI53+ZW
36 | kuHCpogxKCGNim100PhRYvxq/OZhGu6wmq77fOcGMKmubDiLSEwajeABb4z9
37 | Ylllf8uQIoj/By4pF+0dv+mOOGejeRbRac/B4I+4kCa8CSWpPl49ln+rpEub
38 | LuPmyCz89X6V/QNY0f7tz/0OxKN+Xa5guNkcXi76OMgbuNK4rWrwzGS/W0Ps
39 | f8cKg99McgSWkJG4y26hUJNJD6zckz6JnZNgN5KbhxCcZG8xVbyiVef4wDkN
40 | 6SFtDu13ZWvP9KyICtY49+WYQR7uwq1POMEUL4FCzHisbJcsFsoSfZRe3Ym8
41 | PxoaKF+AjflkQ+oLRNhqgmnOhLDc0B+0qEb3yn29M3P+wO1TtM5i46OJ0Em7
42 | LLiKaCR+nsLA1gJyrwlMj6zoRVUJCOjmWVIAT0BgxUHB/vSC7h37Te9Milqb
43 | SqIsr5nnz8jtauFNWmEMJ4dsQzR/SwiX+knAv5Zf6v/6fPcuc1gPJz2Cmnzq
44 | 0RG5W4ViQdSPMUbOwU0EYEM4aQEQANRb9WI1lVWJsAx+YQFB76lEyE6DWo9l
45 | wjq0QdN/ruSTrHxyZhQu/Gb32QUaQ9kWhLfbuLC7R5TkeZeStieFrPvaI5J8
46 | oIWgKJ4zWxq+cBAcUqbb0J35Dp6ksZZEofkhETGUVJz9Ul7GGzK6oiSR2Bc1
47 | i1/T7E17qe8LIvsJWhJSeB/1xsCjRoLCnzjF0Hgp8uCBj/aqdd9//pWiiP4C
48 | KI9LDBlz5IkkCv6dYho8tWDCdgqCKg3JKCpRaW6Pk33nhGXF72c5EhtjvQkv
49 | ThIzf03zV0L9ZwcMiV5l/TIUWAKbVPPNyekQNuQERP8vA6aI6WBBVdlVdOMN
50 | lRq33RxhLRyd7CNVwr6dSEaIIXQWFYOAVP0b8QeTvrz/aXih5a6RbaWF6Ikc
51 | BO3alIAbgCzuVstEKgGtO2+HtfR9qCbsX9IzXwVaJ7PPsTqfGhKENTZzAHCK
52 | tZgp94Sau2aVN2jjljWTMalT9kv61mKmDVkkgCfeFDcP3etadR/2dSuCLqst
53 | KXgw0QvnAAfKNqwA7HNM/iOErATMV1uqVXFh5ArgLr7wl35vSmr84oNl7A5T
54 | tSlLBfCdgVOOE2kVHpn3DIbTxzWVttXjRblMuWpFmLt63xh9SmZo0NagcIQE
55 | kxsSypugGOaH3Qm7PuzGEklG46KHaAq7gELcdKaM9Tfn1Aq4ZYqlABEBAAHC
56 | wV8EGAEIAAkFAmBDOGkCGwwACgkQ6JWMvvXNisY38xAA8+G9upsq/zWPSSHH
57 | baSOxFiYWGpG2BEBkU3bhy/60w0X8l2GzIV77QKhT3xbOTOBsSMs/IGuihQN
58 | CFBMvod4UcclTD3i6KGNEhNGZ0yM8l/xsW7jEyD3VqoTcErB/4lysjJDlWgq
59 | nGYdrJIsVUxJ9u6DUOIdgTxLUQ8oo6C55SfGUfBW2oEELSaGqcHTHe5c7wTR
60 | LBKyCJ+XRJGoBc3dIXTNSekDUNXTCaSZMi8LCK4stqKgO587ru+0pfwErvx4
61 | nVLjg6vNZ8ueagtjxFcX7mBEyd0e9lnSvVaeOPclr3MurMSHWyA00HAUQicr
62 | v+iXl8jRqK7jMGO3apH4SuaQeK/wS29FoggJNKU9MEM41jUy2XTW9dyrBKIq
63 | JqzhozeU7xjKYYAaTKv/6L78WI/bqBn121IyBMzI1PkkEcGKx4JGhSyWOQs7
64 | HvZlzy01CmOWNmPf2ddHeKiGQH48BnZE4glKlGmDfjXzPF7ilSEer3RgkffE
65 | 8mkwh3yC11HU8P/wZPpM4XOfI/PPIwOnvuTkQugR2sVPAlyLPfCw7bgDih2Q
66 | 0w7znJtw2ASmz6ud8lWMXyn8LsZbk7/twt7dWX0ygfLi7w1CnLcYC4tJo+vt
67 | rOBuIGX/ZY0KCZaElfbK6s6I8vcxj9b979bZwOkLrOfT1liAhH9n6ssuCaGL
68 | /J9+N+I=
69 | =kKHj
70 |
71 | -----END PGP PUBLIC KEY BLOCK-----
72 | ```
73 |
--------------------------------------------------------------------------------
/acr/README.md:
--------------------------------------------------------------------------------
1 | Setup
2 |
3 | # For amd64
4 | export ARCH=amd64
5 | docker-compose up
6 |
7 | # For arm64
8 | export ARCH=arm64
9 | docker-compose up
10 |
11 |
12 | Go in the Bowser to:
13 |
14 | `http://localhost:5000`
15 |
16 | Signup up and login to use your local installation.
17 |
18 |
--------------------------------------------------------------------------------
/acr/docker-compose.yml:
--------------------------------------------------------------------------------
1 | x-platform: &platform
2 | platform: ${PLATFORM:-linux/amd64}
3 |
4 | services:
5 | server:
6 | image: ${AZURE_REGISTRY_NAME}.azurecr.io/betterscan-server:${ARCH:-amd64}-latest
7 | restart: always
8 | environment:
9 | OPENAI_GPT_API: ${OPENAI_GPT_API}
10 | depends_on:
11 | - postgres
12 | working_dir: /srv/betterscan/
13 | entrypoint: sh
14 | command: -c "mkdir -p data1/repositories data2/tasks setup_state && if [ -f /srv/betterscan/setup_state/setup_done ]; then python3.8 /srv/betterscan/manage.py runserver; else python3.8 /srv/betterscan/manage.py setup && touch /srv/betterscan/setup_state/setup_done; fi"
15 | ports:
16 | - 5001:5000
17 | volumes:
18 | - data1:/srv/betterscan/quantifiedcode/data/
19 | - data2:/srv/betterscan/quantifiedcode/backend/data/tasks
20 | - setup_state:/srv/betterscan/setup_state
21 | <<: *platform
22 |
23 | postgres:
24 | image: postgres:13.2
25 | restart: always
26 | environment:
27 | POSTGRES_DB: qc
28 | POSTGRES_USER: qc
29 | POSTGRES_PASSWORD: qc
30 | PGDATA: /var/lib/postgresql/data/pgdata
31 | ports:
32 | - "5432:5432"
33 | volumes:
34 | - db-data:/var/lib/postgresql/data
35 |
36 | worker_1:
37 | image: ${AZURE_REGISTRY_NAME}.azurecr.io/betterscan-worker:${ARCH:-amd64}-latest
38 | ulimits:
39 | stack: -1
40 | restart: always
41 | environment:
42 | OPENAI_GPT_API: ${OPENAI_GPT_API}
43 | hostname: worker_1
44 | depends_on:
45 | - rabbitmq3
46 | - postgres
47 | - server
48 | working_dir: /srv/betterscan/
49 | entrypoint: sh
50 | command: -c "python3.8 /srv/betterscan/manage.py runworker"
51 | volumes:
52 | - data1:/srv/betterscan/quantifiedcode/data/
53 | - data2:/srv/betterscan/quantifiedcode/backend/data/tasks
54 | <<: *platform
55 |
56 | rabbitmq3:
57 | container_name: "rabbitmq"
58 | image: rabbitmq:3.8-management-alpine
59 | environment:
60 | - RABBITMQ_DEFAULT_USER=qc
61 | - RABBITMQ_DEFAULT_PASS=qc
62 | ports:
63 | - 5672:5672
64 | - 15672:15672
65 | healthcheck:
66 | test: [ "CMD", "nc", "-z", "localhost", "5672" ]
67 | interval: 5s
68 | timeout: 15s
69 | retries: 1
70 |
71 | volumes:
72 | data1:
73 | driver: local
74 | data2:
75 | driver: local
76 | setup_state:
77 | driver: local
78 | db-data:
79 | driver: local
80 |
81 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | [This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.]
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 |
474 | Copyright (C)
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
489 | USA
490 |
491 | Also add information on how to contact you by electronic and paper mail.
492 |
493 | You should also get your employer (if you work as a programmer) or your
494 | school, if any, to sign a "copyright disclaimer" for the library, if
495 | necessary. Here is a sample; alter the names:
496 |
497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
498 | library `Frob' (a library for tweaking knobs) written by James Random
499 | Hacker.
500 |
501 | , 1 April 1990
502 | Ty Coon, President of Vice
503 |
504 | That's all there is to it!
505 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/custom.yaml:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 | rules:
5 | - id: detected-log4j-core
6 | pattern-either:
7 | - pattern-regex: log4j-core[<>a-zA-Z0-9\/\n \r.-]{1,100}2\.(([0-9][^0-9])|(1[0-6]))
8 | - pattern-regex: 2\.(([0-9][^0-9])|(1[0-6]))[<>a-zA-Z0-9\/\n \r.-]{1,100}log4j-core
9 | - pattern-regex: log4j-core['", a-zA-Z]{1,10}version[:'" =]{1,5}2\.(([0-9][^0-9])|(1[0-6]))
10 | - pattern-regex: log4j-core['", a-zA-Z]{1,10}rev['" =]{1,5}2\.(([0-9][^0-9])|(1[0-6]))
11 | languages: [regex]
12 | message: log4j-core insecure version detected
13 | severity: ERROR
14 | metadata:
15 | category: security
16 |
17 | - id: log4j-message-injection
18 | metadata:
19 | category: security
20 | technology:
21 | - java
22 | message: Possible Lookup injection into Log4j messages.
23 | patterns:
24 | # Checks for error(...), warn(...), info(...), debug(...), fatal(...), trace(...), log(level, ...):
25 | - pattern-either:
26 | - pattern: (org.apache.logging.log4j.Logger $W).fatal($X + $Y, ...);
27 | - pattern: |
28 | String $MSG = $X + $Y;
29 | ...
30 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
31 | - pattern: |
32 | String $MSG = $X;
33 | ...
34 | $MSG += $Y;
35 | ...
36 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
37 | - pattern: (org.apache.logging.log4j.Logger $W).fatal(String.format($X, ...), ...);
38 | - pattern: |
39 | String $MSG = String.format($X, ...);
40 | ...
41 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
42 | - pattern: |
43 | String $MSG = $X;
44 | ...
45 | $MSG += String.format(...);
46 | ...
47 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
48 | - pattern: (org.apache.logging.log4j.Logger $W).error($X + $Y, ...);
49 | - pattern: |
50 | String $MSG = $X + $Y;
51 | ...
52 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
53 | - pattern: |
54 | String $MSG = $X;
55 | ...
56 | $MSG += $Y;
57 | ...
58 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
59 | - pattern: (org.apache.logging.log4j.Logger $W).error(String.format($X, ...), ...);
60 | - pattern: |
61 | String $MSG = String.format($X, ...);
62 | ...
63 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
64 | - pattern: |
65 | String $MSG = $X;
66 | ...
67 | $MSG += String.format(...);
68 | ...
69 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
70 | - pattern: (org.apache.logging.log4j.Logger $W).warn($X + $Y, ...);
71 | - pattern: |
72 | String $MSG = $X + $Y;
73 | ...
74 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
75 | - pattern: |
76 | String $MSG = $X;
77 | ...
78 | $MSG += $Y;
79 | ...
80 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
81 | - pattern: (org.apache.logging.log4j.Logger $W).warn(String.format($X, ...), ...);
82 | - pattern: |
83 | String $MSG = String.format($X, ...);
84 | ...
85 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
86 | - pattern: |
87 | String $MSG = $X;
88 | ...
89 | $MSG += String.format(...);
90 | ...
91 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
92 | - pattern: (org.apache.logging.log4j.Logger $W).info($X + $Y, ...);
93 | - pattern: |
94 | String $MSG = $X + $Y;
95 | ...
96 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
97 | - pattern: |
98 | String $MSG = $X;
99 | ...
100 | $MSG += $Y;
101 | ...
102 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
103 | - pattern: (org.apache.logging.log4j.Logger $W).info(String.format($X, ...), ...);
104 | - pattern: |
105 | String $MSG = String.format($X, ...);
106 | ...
107 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
108 | - pattern: |
109 | String $MSG = $X;
110 | ...
111 | $MSG += String.format(...);
112 | ...
113 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
114 | - pattern: (org.apache.logging.log4j.Logger $W).debug($X + $Y, ...);
115 | - pattern: |
116 | String $MSG = $X + $Y;
117 | ...
118 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
119 | - pattern: |
120 | String $MSG = $X;
121 | ...
122 | $MSG += $Y;
123 | ...
124 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
125 | - pattern: (org.apache.logging.log4j.Logger $W).debug(String.format($X, ...), ...);
126 | - pattern: |
127 | String $MSG = String.format($X, ...);
128 | ...
129 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
130 | - pattern: |
131 | String $MSG = $X;
132 | ...
133 | $MSG += String.format(...);
134 | ...
135 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
136 | - pattern: (org.apache.logging.log4j.Logger $W).trace($X + $Y, ...);
137 | - pattern: |
138 | String $MSG = $X + $Y;
139 | ...
140 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
141 | - pattern: |
142 | String $MSG = $X;
143 | ...
144 | $MSG += $Y;
145 | ...
146 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
147 | - pattern: (org.apache.logging.log4j.Logger $W).trace(String.format($X, ...), ...);
148 | - pattern: |
149 | String $MSG = String.format($X, ...);
150 | ...
151 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
152 | - pattern: |
153 | String $MSG = $X;
154 | ...
155 | $MSG += String.format(...);
156 | ...
157 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
158 | - pattern: (org.apache.logging.log4j.Logger $W).log($LEVEL, $X + $Y, ...);
159 | - pattern: |
160 | String $MSG = $X + $Y;
161 | ...
162 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
163 | - pattern: |
164 | String $MSG = $X;
165 | ...
166 | $MSG += $Y;
167 | ...
168 | (org.apache.logging.log4j.Logger $W).log($LEVEL, MSG, ...);
169 | - pattern: (org.apache.logging.log4j.Logger $W).log($LEVEL, String.format($X, ...), ...);
170 | - pattern: |
171 | String $MSG = String.format($X, ...);
172 | ...
173 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
174 | - pattern: |
175 | String $MSG = $X;
176 | ...
177 | $MSG += String.format(...);
178 | ...
179 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
180 | severity: WARNING
181 | languages:
182 | - java
183 |
184 | - id: spring-controller-exists
185 | patterns:
186 | - pattern-either:
187 | - pattern: import org.springframework.web.bind.annotation.RestController;
188 | - pattern: import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
189 | message: |
190 | Found a Spring RestController
191 | Make sure you are not vulnerable or have the possible mitigations
192 | https://www.praetorian.com/blog/spring-core-jdk9-rce/
193 | languages:
194 | - java
195 | severity: INFO
196 | metadata:
197 | references:
198 | - https://www.praetorian.com/blog/spring-core-jdk9-rce/
199 | - https://www.cyberkendra.com/2022/03/spring4shell-details-and-exploit-code.html
200 | category: security
201 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/detected-log4j-core.xml:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 |
5 |
6 | org.projectlombok
7 | lombok
8 | 1.18.6
9 |
10 |
11 |
12 |
13 |
14 | org.apache.logging.log4j
15 | log4j-core
16 | 2.12.1
17 |
18 |
19 |
24 |
25 |
26 | org.apache.logging.log4j
27 | log4j-slf4j-impl
28 | 2.11.1
29 |
30 |
31 |
36 |
37 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/detected-log4j-core.yaml:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 | rules:
5 | - id: detected-log4j-core
6 | pattern-either:
7 | - pattern-regex: log4j-core[<>a-zA-Z0-9\/\n \r.-]{1,100}2\.(([0-9][^0-9])|(1[0-6]))
8 | - pattern-regex: 2\.(([0-9][^0-9])|(1[0-6]))[<>a-zA-Z0-9\/\n \r.-]{1,100}log4j-core
9 | - pattern-regex: log4j-core['", a-zA-Z]{1,10}version[:'" =]{1,5}2\.(([0-9][^0-9])|(1[0-6]))
10 | - pattern-regex: log4j-core['", a-zA-Z]{1,10}rev['" =]{1,5}2\.(([0-9][^0-9])|(1[0-6]))
11 | languages: [regex]
12 | message: log4j-core insecure version detected
13 | severity: ERROR
14 | metadata:
15 | category: security
16 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/log4j-message-injection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 | package rules.custom.main;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 |
8 | public class Logger1 {
9 |
10 | public void info(String str) {
11 | System.out.println(str);
12 | }
13 |
14 | public static void main(String[] args) {
15 | Logger1 logger = new Logger1();
16 | logger.info("str"+"ss");
17 |
18 | }
19 | }
20 |
21 | public class Main{
22 | Logger logger = LogManager.getLogger(Main.class.getName());
23 | public void main(String[] args) {
24 | logger.error("ss"+"ss");
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/log4j-message-injection.yaml:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 | rules:
5 | - id: log4j-message-injection
6 | metadata:
7 | category: security
8 | technology:
9 | - java
10 | message: Possible Lookup injection into Log4j messages.
11 | patterns:
12 | # Checks for error(...), warn(...), info(...), debug(...), fatal(...), trace(...), log(level, ...):
13 | - pattern-either:
14 | - pattern: (org.apache.logging.log4j.Logger $W).fatal($X + $Y, ...);
15 | - pattern: |
16 | String $MSG = $X + $Y;
17 | ...
18 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
19 | - pattern: |
20 | String $MSG = $X;
21 | ...
22 | $MSG += $Y;
23 | ...
24 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
25 | - pattern: (org.apache.logging.log4j.Logger $W).fatal(String.format($X, ...), ...);
26 | - pattern: |
27 | String $MSG = String.format($X, ...);
28 | ...
29 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
30 | - pattern: |
31 | String $MSG = $X;
32 | ...
33 | $MSG += String.format(...);
34 | ...
35 | (org.apache.logging.log4j.Logger $W).fatal($MSG, ...);
36 |
37 |
38 | - pattern: (org.apache.logging.log4j.Logger $W).error($X + $Y, ...);
39 | - pattern: |
40 | String $MSG = $X + $Y;
41 | ...
42 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
43 | - pattern: |
44 | String $MSG = $X;
45 | ...
46 | $MSG += $Y;
47 | ...
48 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
49 | - pattern: (org.apache.logging.log4j.Logger $W).error(String.format($X, ...), ...);
50 | - pattern: |
51 | String $MSG = String.format($X, ...);
52 | ...
53 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
54 | - pattern: |
55 | String $MSG = $X;
56 | ...
57 | $MSG += String.format(...);
58 | ...
59 | (org.apache.logging.log4j.Logger $W).error($MSG, ...);
60 |
61 | - pattern: (org.apache.logging.log4j.Logger $W).warn($X + $Y, ...);
62 | - pattern: |
63 | String $MSG = $X + $Y;
64 | ...
65 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
66 | - pattern: |
67 | String $MSG = $X;
68 | ...
69 | $MSG += $Y;
70 | ...
71 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
72 | - pattern: (org.apache.logging.log4j.Logger $W).warn(String.format($X, ...), ...);
73 | - pattern: |
74 | String $MSG = String.format($X, ...);
75 | ...
76 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
77 | - pattern: |
78 | String $MSG = $X;
79 | ...
80 | $MSG += String.format(...);
81 | ...
82 | (org.apache.logging.log4j.Logger $W).warn($MSG, ...);
83 |
84 |
85 | - pattern: (org.apache.logging.log4j.Logger $W).info($X + $Y, ...);
86 | - pattern: |
87 | String $MSG = $X + $Y;
88 | ...
89 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
90 | - pattern: |
91 | String $MSG = $X;
92 | ...
93 | $MSG += $Y;
94 | ...
95 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
96 | - pattern: (org.apache.logging.log4j.Logger $W).info(String.format($X, ...), ...);
97 | - pattern: |
98 | String $MSG = String.format($X, ...);
99 | ...
100 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
101 | - pattern: |
102 | String $MSG = $X;
103 | ...
104 | $MSG += String.format(...);
105 | ...
106 | (org.apache.logging.log4j.Logger $W).info($MSG, ...);
107 |
108 |
109 | - pattern: (org.apache.logging.log4j.Logger $W).debug($X + $Y, ...);
110 | - pattern: |
111 | String $MSG = $X + $Y;
112 | ...
113 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
114 | - pattern: |
115 | String $MSG = $X;
116 | ...
117 | $MSG += $Y;
118 | ...
119 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
120 | - pattern: (org.apache.logging.log4j.Logger $W).debug(String.format($X, ...), ...);
121 | - pattern: |
122 | String $MSG = String.format($X, ...);
123 | ...
124 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
125 | - pattern: |
126 | String $MSG = $X;
127 | ...
128 | $MSG += String.format(...);
129 | ...
130 | (org.apache.logging.log4j.Logger $W).debug($MSG, ...);
131 |
132 | - pattern: (org.apache.logging.log4j.Logger $W).trace($X + $Y, ...);
133 | - pattern: |
134 | String $MSG = $X + $Y;
135 | ...
136 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
137 | - pattern: |
138 | String $MSG = $X;
139 | ...
140 | $MSG += $Y;
141 | ...
142 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
143 | - pattern: (org.apache.logging.log4j.Logger $W).trace(String.format($X, ...), ...);
144 | - pattern: |
145 | String $MSG = String.format($X, ...);
146 | ...
147 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
148 | - pattern: |
149 | String $MSG = $X;
150 | ...
151 | $MSG += String.format(...);
152 | ...
153 | (org.apache.logging.log4j.Logger $W).trace($MSG, ...);
154 |
155 | - pattern: (org.apache.logging.log4j.Logger $W).log($LEVEL, $X + $Y, ...);
156 | - pattern: |
157 | String $MSG = $X + $Y;
158 | ...
159 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
160 | - pattern: |
161 | String $MSG = $X;
162 | ...
163 | $MSG += $Y;
164 | ...
165 | (org.apache.logging.log4j.Logger $W).log($LEVEL, MSG, ...);
166 | - pattern: (org.apache.logging.log4j.Logger $W).log($LEVEL, String.format($X, ...), ...);
167 | - pattern: |
168 | String $MSG = String.format($X, ...);
169 | ...
170 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
171 | - pattern: |
172 | String $MSG = $X;
173 | ...
174 | $MSG += String.format(...);
175 | ...
176 | (org.apache.logging.log4j.Logger $W).log($LEVEL, $MSG, ...);
177 | severity: WARNING
178 | languages:
179 | - java
180 |
--------------------------------------------------------------------------------
/analyzers/custom-semgrep/rules/custom/spring-controller-exists.yaml:
--------------------------------------------------------------------------------
1 | /*
2 | * See the original LICENSE in analyzers/custom-semgrep/LICENSE file for details.
3 | */
4 | rules:
5 | - id: spring-controller-exists
6 | patterns:
7 | - pattern-either:
8 | - pattern: import org.springframework.web.bind.annotation.RestController;
9 | - pattern: import
10 | org.springframework.web.servlet.mvc.multiaction.MultiActionController;
11 | message: |
12 | Found a Spring RestController
13 |
14 | Make sure you are not vulnerable or have the possible mitigations
15 | https://www.praetorian.com/blog/spring-core-jdk9-rce/
16 | languages:
17 | - java
18 | severity: INFO
19 | metadata:
20 | references:
21 | - https://www.praetorian.com/blog/spring-core-jdk9-rce/
22 | - https://www.cyberkendra.com/2022/03/spring4shell-details-and-exploit-code.html
23 | category: security
24 |
--------------------------------------------------------------------------------
/analyzers/eslint.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of Betterscan CE (Community Edition).
3 | #
4 | # Betterscan is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU Affero General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # Betterscan is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU Affero General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Affero General Public License
15 | # along with Betterscan. If not, see .
16 | #
17 | # Originally licensed under the BSD-3-Clause license with parts changed under
18 | # LGPL v2.1 with Commons Clause.
19 | # See the original LICENSE file for details.
20 | #
21 | rules:
22 | - id: eslint.detect-no-csrf-before-method-override
23 | metadata:
24 | cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)'
25 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-no-csrf-before-method-override.js
26 | references:
27 | - https://github.com/nodesecurity/eslint-plugin-security/blob/master/docs/bypass-connect-csrf-protection-by-abusing.md
28 | message: |
29 | Detected use of express.csrf() middleware before express.methodOverride(). This can
30 | allow GET requests (which are not checked by csrf) to turn into POST requests later.
31 | pattern: |
32 | express.csrf();
33 | ...
34 | express.methodOverride();
35 | severity: WARNING
36 | languages:
37 | - javascript
38 | - typescript
39 |
40 | - id: eslint.detect-eval-with-expression
41 | metadata:
42 | cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
43 | owasp: 'A1: Injection'
44 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-eval-with-expression.js
45 | message: |
46 | Detected eval(variable), which could allow a malicious actor to run arbitrary code.
47 | patterns:
48 | - pattern: eval($OBJ)
49 | - pattern-not: eval("...")
50 | severity: WARNING
51 | languages:
52 | - javascript
53 | - typescript
54 |
55 | - id: eslint.detect-child-process
56 | metadata:
57 | cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
58 | owasp: 'A1: Injection'
59 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js
60 | message: |
61 | Detected non-literal calls to child_process.exec(). This could lead to a command
62 | injection vulnerability.
63 | patterns:
64 | - pattern: child_process.exec(...)
65 | - pattern-not: child_process.exec('...')
66 | severity: WARNING
67 | languages:
68 | - javascript
69 | - typescript
70 |
71 | - id: eslint.detect-pseudoRandomBytes
72 | metadata:
73 | cwe: 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)'
74 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-pseudoRandomBytes.js
75 | message: |
76 | Detected usage of crypto.pseudoRandomBytes, which does not produce secure random numbers.
77 | pattern: crypto.pseudoRandomBytes
78 | severity: WARNING
79 | languages:
80 | - javascript
81 | - typescript
82 |
83 | - id: eslint.detect-disable-mustache-escape
84 | metadata:
85 | cwe: 'CWE-79: Improper Neutralization of Input During Web Page Generation (XSS)'
86 | owasp: 'A7: Cross-Site Scripting XSS'
87 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-disable-mustache-escape.js
88 | message: |
89 | Markup escaping disabled. This can be used with some template engines to escape
90 | disabling of HTML entities, which can lead to XSS attacks.
91 | pattern: $OBJ.escapeMarkup = false
92 | severity: WARNING
93 | languages:
94 | - javascript
95 | - typescript
96 |
97 | - id: eslint.detect-non-literal-require
98 | metadata:
99 | cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
100 | owasp: 'A1: Injection'
101 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js
102 | message: |
103 | Detected the use of require(variable). Calling require with a non-literal argument might
104 | allow an attacker to load an run arbitrary code, or access arbitrary files.
105 | patterns:
106 | - pattern: require($OBJ)
107 | - pattern-not: require('...')
108 | severity: WARNING
109 | languages:
110 | - javascript
111 | - typescript
112 |
113 | - id: eslint.detect-buffer-noassert
114 | metadata:
115 | cwe: 'CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer'
116 | source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-buffer-noassert.js
117 | message: |
118 | Detected usage of noassert in Buffer API, which allows the offset the be beyond the
119 | end of the buffer. This could result in writing or reading beyond the end of the buffer.
120 | pattern-either:
121 | - pattern: $OBJ.readUInt8(..., true)
122 | - pattern: $OBJ.readUInt16LE(..., true)
123 | - pattern: $OBJ.readUInt16BE(..., true)
124 | - pattern: $OBJ.readUInt32LE(..., true)
125 | - pattern: $OBJ.readUInt32BE(..., true)
126 | - pattern: $OBJ.readInt8(..., true)
127 | - pattern: $OBJ.readInt16LE(..., true)
128 | - pattern: $OBJ.readInt16BE(..., true)
129 | - pattern: $OBJ.readInt32LE(..., true)
130 | - pattern: $OBJ.readInt32BE(..., true)
131 | - pattern: $OBJ.readFloatLE(..., true)
132 | - pattern: $OBJ.readFloatBE(..., true)
133 | - pattern: $OBJ.readDoubleLE(..., true)
134 | - pattern: $OBJ.readDoubleBE(..., true)
135 | - pattern: $OBJ.writeUInt8(..., true)
136 | - pattern: $OBJ.writeUInt16LE(..., true)
137 | - pattern: $OBJ.writeUInt16BE(..., true)
138 | - pattern: $OBJ.writeUInt32LE(..., true)
139 | - pattern: $OBJ.writeUInt32BE(..., true)
140 | - pattern: $OBJ.writeInt8(..., true)
141 | - pattern: $OBJ.writeInt16LE(..., true)
142 | - pattern: $OBJ.writeInt16BE(..., true)
143 | - pattern: $OBJ.writeInt32LE(..., true)
144 | - pattern: $OBJ.writeInt32BE(..., true)
145 | - pattern: $OBJ.writeFloatLE(..., true)
146 | - pattern: $OBJ.writeFloatBE(..., true)
147 | - pattern: $OBJ.writeDoubleLE(..., true)
148 | - pattern: $OBJ.writeDoubleBE(..., true)
149 | severity: WARNING
150 | languages:
151 | - javascript
152 | - typescript
153 |
154 |
155 | - id: eslint.detect-non-literal-fs-filename
156 | patterns:
157 | - pattern-not: $MOD.appendFile("...", ...)
158 | - pattern-not: $MOD.appendFileSync("...", ...)
159 | - pattern-not: $MOD.chmod("...", ...)
160 | - pattern-not: $MOD.chmodSync("...", ...)
161 | - pattern-not: $MOD.chown("...", ...)
162 | - pattern-not: $MOD.chownSync("...", ...)
163 | - pattern-not: $MOD.createReadStream("...", ...)
164 | - pattern-not: $MOD.createWriteStream("...", ...)
165 | - pattern-not: $MOD.exists("...", ...)
166 | - pattern-not: $MOD.existsSync("...", ...)
167 | - pattern-not: $MOD.lchmod("...", ...)
168 | - pattern-not: $MOD.lchmodSync("...", ...)
169 | - pattern-not: $MOD.lchown("...", ...)
170 | - pattern-not: $MOD.lchownSync("...", ...)
171 | - pattern-not: $MOD.link("...", "...", ...)
172 | - pattern-not: $MOD.linkSync("...", "...", ...)
173 | - pattern-not: $MOD.lstat("...", ...)
174 | - pattern-not: $MOD.lstatSync("...", ...)
175 | - pattern-not: $MOD.mkdir("...", ...)
176 | - pattern-not: $MOD.mkdirSync("...", ...)
177 | - pattern-not: $MOD.open("...", ...)
178 | - pattern-not: $MOD.openSync("...", ...)
179 | - pattern-not: $MOD.readdir("...", ...)
180 | - pattern-not: $MOD.readdirSync("...", ...)
181 | - pattern-not: $MOD.readFile("...", ...)
182 | - pattern-not: $MOD.readFileSync("...", ...)
183 | - pattern-not: $MOD.readlink("...", ...)
184 | - pattern-not: $MOD.readlinkSync("...", ...)
185 | - pattern-not: $MOD.realpath("...", ...)
186 | - pattern-not: $MOD.realpathSync("...", ...)
187 | - pattern-not: $MOD.rename("...", "...", ...)
188 | - pattern-not: $MOD.renameSync("...", "...", ...)
189 | - pattern-not: $MOD.rmdir("...", ...)
190 | - pattern-not: $MOD.rmdirSync("...", ...)
191 | - pattern-not: $MOD.stat("...", ...)
192 | - pattern-not: $MOD.statSync("...", ...)
193 | - pattern-not: $MOD.symlink("...", "...", ...)
194 | - pattern-not: $MOD.symlinkSync("...", "...", ...)
195 | - pattern-not: $MOD.truncate("...", ...)
196 | - pattern-not: $MOD.truncateSync("...", ...)
197 | - pattern-not: $MOD.unlink("...", ...)
198 | - pattern-not: $MOD.unlinkSync("...", ...)
199 | - pattern-not: $MOD.unwatchFile("...", ...)
200 | - pattern-not: $MOD.utimes("...", ...)
201 | - pattern-not: $MOD.utimesSync("...", ...)
202 | - pattern-not: $MOD.watch("...", ...)
203 | - pattern-not: $MOD.watchFile("...", ...)
204 | - pattern-not: $MOD.writeFile("...", ...)
205 | - pattern-not: $MOD.writeFileSync("...", ...)
206 | - pattern-either:
207 | - pattern: $MOD.appendFile(...)
208 | - pattern: $MOD.appendFileSync(...)
209 | - pattern: $MOD.chmod(...)
210 | - pattern: $MOD.chmodSync(...)
211 | - pattern: $MOD.chown(...)
212 | - pattern: $MOD.chownSync(...)
213 | - pattern: $MOD.createReadStream(...)
214 | - pattern: $MOD.createWriteStream(...)
215 | - pattern: $MOD.exists(...)
216 | - pattern: $MOD.existsSync(...)
217 | - pattern: $MOD.lchmod(...)
218 | - pattern: $MOD.lchmodSync(...)
219 | - pattern: $MOD.lchown(...)
220 | - pattern: $MOD.lchownSync(...)
221 | - pattern: $MOD.link(...)
222 | - pattern: $MOD.linkSync(...)
223 | - pattern: $MOD.lstat(...)
224 | - pattern: $MOD.lstatSync(...)
225 | - pattern: $MOD.mkdir(...)
226 | - pattern: $MOD.mkdirSync(...)
227 | - pattern: $MOD.open(...)
228 | - pattern: $MOD.openSync(...)
229 | - pattern: $MOD.readdir(...)
230 | - pattern: $MOD.readdirSync(...)
231 | - pattern: $MOD.readFile(...)
232 | - pattern: $MOD.readFileSync(...)
233 | - pattern: $MOD.readlink(...)
234 | - pattern: $MOD.readlinkSync(...)
235 | - pattern: $MOD.realpath(...)
236 | - pattern: $MOD.realpathSync(...)
237 | - pattern: $MOD.rename(...)
238 | - pattern: $MOD.renameSync(...)
239 | - pattern: $MOD.rmdir(...)
240 | - pattern: $MOD.rmdirSync(...)
241 | - pattern: $MOD.stat(...)
242 | - pattern: $MOD.statSync(...)
243 | - pattern: $MOD.symlink(...)
244 | - pattern: $MOD.symlinkSync(...)
245 | - pattern: $MOD.truncate(...)
246 | - pattern: $MOD.truncateSync(...)
247 | - pattern: $MOD.unlink(...)
248 | - pattern: $MOD.unlinkSync(...)
249 | - pattern: $MOD.unwatchFile(...)
250 | - pattern: $MOD.utimes(...)
251 | - pattern: $MOD.utimesSync(...)
252 | - pattern: $MOD.watch(...)
253 | - pattern: $MOD.watchFile(...)
254 | - pattern: $MOD.writeFile(...)
255 | - pattern: $MOD.writeFileSync(...)
256 | message: |
257 | A variable is present in the filename argument of fs calls, this might allow an attacker to access anything on your system.
258 | languages:
259 | - typescript
260 | - javascript
261 | severity: WARNING
262 | metadata:
263 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')"
264 |
265 | - id: eslint.detect-object-injection
266 | patterns:
267 | - pattern: $O[$ARG]
268 | - pattern-not: $O["..."]
269 | - pattern-not: "$O[($ARG : float)]"
270 | - pattern-not-inside: |
271 | $ARG = [$V];
272 | ...
273 | <... $O[$ARG] ...>;
274 | - pattern-not-inside: |
275 | $ARG = $V;
276 | ...
277 | <... $O[$ARG] ...>;
278 | - metavariable-regex:
279 | metavariable: $ARG
280 | regex: (?![0-9]+)
281 | message: "Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype, leading to possible code execution."
282 | languages:
283 | - javascript
284 | - typescript
285 | severity: WARNING
286 | metadata:
287 | cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
288 |
--------------------------------------------------------------------------------
/analyzers/find_sec_bugs.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of Betterscan CE (Community Edition).
3 | #
4 | # Betterscan is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU Affero General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # Betterscan is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU Affero General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Affero General Public License
15 | # along with Betterscan. If not, see .
16 | #
17 | # Originally licensed under the BSD-3-Clause license with parts changed under
18 | # LGPL v2.1 with Commons Clause.
19 | # See the original LICENSE file for details.
20 | #
21 |
22 | # yamllint disable
23 | # rule-set version: v1.0.44
24 | # yamllint enable
25 | ---
26 | rules:
27 | - id: "find_sec_bugs.HTTPONLY_COOKIE-1"
28 | pattern-either:
29 | - patterns:
30 | - pattern: |
31 | javax.servlet.http.Cookie $C = new Cookie(..., ...);
32 | ...
33 | (HttpServletResponse $RESP).addCookie($C);
34 | - pattern-not-inside: |
35 | javax.servlet.http.Cookie $C = new Cookie(..., ...);
36 | ...
37 | $C.setHttpOnly(true);
38 | ...
39 | (HttpServletResponse $RESP).addCookie($C);
40 | - pattern: "(javax.servlet.http.Cookie $C).setHttpOnly(false);"
41 | message: |
42 | A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the
43 | browser to make sure that the cookie can not be red by malicious script. When a user is the
44 | target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session
45 | id for example.
46 | languages:
47 | - "java"
48 | severity: "WARNING"
49 | metadata:
50 | category: "security"
51 | cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag"
52 | technology:
53 | - "java"
54 | - id: "find_sec_bugs.INSECURE_COOKIE-1"
55 | pattern-either:
56 | - patterns:
57 | - pattern: |
58 | javax.servlet.http.Cookie $C = new Cookie(..., ...);
59 | ...
60 | (HttpServletResponse $RESP).addCookie($C);
61 | - pattern-not-inside: |
62 | javax.servlet.http.Cookie $C = new Cookie(..., ...);
63 | ...
64 | $C.setSecure(true);
65 | ...
66 | (HttpServletResponse $RESP).addCookie($C);
67 | - pattern: "(javax.servlet.http.Cookie $C).setSecure(false);"
68 | message: |
69 | "Storing sensitive data in a persistent cookie for an extended period can lead to a breach of
70 | confidentiality or account compromise."
71 | languages:
72 | - "java"
73 | severity: "WARNING"
74 | metadata:
75 | category: "security"
76 | cwe: "CWE-539: Information Exposure Through Persistent Cookies"
77 | technology:
78 | - "java"
79 | - id: "find_sec_bugs.COOKIE_PERSISTENT-1"
80 | patterns:
81 | - pattern-inside: |
82 | (javax.servlet.http.Cookie $C).setMaxAge($AGE);
83 | - metavariable-comparison:
84 | metavariable: "$AGE"
85 | comparison: "$AGE >= 31536000"
86 | message: |
87 | A new cookie is created without the Secure flag set. The Secure flag is a directive to the
88 | browser to make sure that the cookie is not sent for insecure communication (http://)
89 | languages:
90 | - "java"
91 | severity: "WARNING"
92 | metadata:
93 | category: "security"
94 | cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
95 | technology:
96 | - "java"
97 | - id: "find_sec_bugs.COOKIE_USAGE-1"
98 | patterns:
99 | - pattern-inside: |
100 | $FUNC(..., HttpServletRequest $REQ, ...) {
101 | ...
102 | }
103 | - pattern-either:
104 | - patterns:
105 | - pattern-inside: |
106 | for (Cookie $C : $REQ.getCookies()) {
107 | ...
108 | }
109 | - pattern-either:
110 | - pattern: "$C.getName();"
111 | - pattern: "$C.getValue();"
112 | - pattern: "$C.getPath();"
113 | - pattern: "(Cookie $COOKIE).getName();"
114 | - pattern: "(Cookie $COOKIE).getValue();"
115 | - pattern: "(Cookie $COOKIE).getPath();"
116 | message: |
117 | The information stored in a custom cookie should not be sensitive or related to the session.
118 | In most cases, sensitive data should only be stored in session and referenced by the user's
119 | session cookie.
120 | languages:
121 | - "java"
122 | severity: "WARNING"
123 | metadata:
124 | category: "security"
125 | cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
126 | technology:
127 | - "java"
128 | - id: "find_sec_bugs.HTTP_RESPONSE_SPLITTING-1"
129 | mode: "taint"
130 | pattern-sources:
131 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameter(...);"
132 | pattern-sanitizers:
133 | - patterns:
134 | - pattern-inside: |
135 | $STR.replaceAll("$REPLACE_CHAR", "$REPLACER");
136 | ...
137 | - pattern: "$STR"
138 | - metavariable-regex:
139 | metavariable: "$REPLACER"
140 | regex: ".*^(CRLF).*"
141 | - metavariable-regex:
142 | metavariable: "$REPLACE_CHAR"
143 | regex: "(*CRLF)"
144 | - pattern: "org.apache.commons.text.StringEscapeUtils.unescapeJava(...);"
145 | pattern-sinks:
146 | - pattern: "new javax.servlet.http.Cookie(\"$KEY\", ...);"
147 | - patterns:
148 | - pattern-inside: |
149 | $C = new javax.servlet.http.Cookie("$KEY", ...);
150 | ...
151 | - pattern: "$C.setValue(...);"
152 | message: |
153 | When an HTTP request contains unexpected CR and LF characters, the server may respond with an
154 | output stream that is interpreted as two different HTTP responses (instead of one). An attacker
155 | can control the second response and mount attacks such as cross-site scripting and cache
156 | poisoning attacks.
157 | languages:
158 | - "java"
159 | severity: "WARNING"
160 | metadata:
161 | category: "security"
162 | cwe: "CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP
163 | Response Splitting')"
164 | technology:
165 | - "java"
166 | - id: "find_sec_bugs.HRS_REQUEST_PARAMETER_TO_COOKIE-1"
167 | mode: "taint"
168 | pattern-sources:
169 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameter(...);"
170 | pattern-sanitizers:
171 | - patterns:
172 | - pattern-inside: |
173 | $STR.replaceAll("$REPLACE_CHAR", "$REPLACER");
174 | ...
175 | - pattern: "$STR"
176 | - metavariable-regex:
177 | metavariable: "$REPLACER"
178 | regex: ".*^(CRLF).*"
179 | - metavariable-regex:
180 | metavariable: "$REPLACE_CHAR"
181 | regex: "(*CRLF)"
182 | - pattern: "org.apache.commons.text.StringEscapeUtils.unescapeJava(...);"
183 | pattern-sinks:
184 | - pattern: "new javax.servlet.http.Cookie(\"$KEY\", ...);"
185 | - patterns:
186 | - pattern-inside: |
187 | $C = new javax.servlet.http.Cookie("$KEY", ...);
188 | ...
189 | - pattern: "$C.setValue(...);"
190 | message: |
191 | This code constructs an HTTP Cookie using an untrusted HTTP parameter. If this cookie is added
192 | to an HTTP response, it will allow a HTTP response splitting vulnerability. See
193 | http://en.wikipedia.org/wiki/HTTP_response_splitting for more information.
194 | languages:
195 | - "java"
196 | severity: "ERROR"
197 | metadata:
198 | category: "security"
199 | cwe: "CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP
200 | Response Splitting')"
201 | technology:
202 | - "java"
203 | - id: "find_sec_bugs.HRS_REQUEST_PARAMETER_TO_HTTP_HEADER-1"
204 | mode: "taint"
205 | pattern-sources:
206 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameter(...);"
207 | pattern-sanitizers:
208 | - patterns:
209 | - pattern-inside: |
210 | $STR.replaceAll("$REPLACE_CHAR", "$REPLACER");
211 | ...
212 | - pattern: "$STR"
213 | - metavariable-regex:
214 | metavariable: "$REPLACER"
215 | regex: ".*^(CRLF).*"
216 | - metavariable-regex:
217 | metavariable: "$REPLACE_CHAR"
218 | regex: "(*CRLF)"
219 | - pattern: "org.apache.commons.text.StringEscapeUtils.unescapeJava(...);"
220 | pattern-sinks:
221 | - pattern: "(javax.servlet.http.HttpServletResponse $RES).setHeader(\"$KEY\", ...);"
222 | - pattern: "(javax.servlet.http.HttpServletResponse $RES).addHeader(\"$KEY\", ...);"
223 | - pattern: "(javax.servlet.http.HttpServletResponseWrapper $WRP).setHeader(\"$KEY\",
224 | ...);"
225 | - pattern: "(javax.servlet.http.HttpServletResponseWrapper $WRP).addHeader(\"$KEY\",
226 | ...);"
227 | message: |
228 | This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP
229 | response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for
230 | more information.
231 | languages:
232 | - "java"
233 | severity: "ERROR"
234 | metadata:
235 | category: "security"
236 | cwe: "CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP
237 | Response Splitting')"
238 | technology:
239 | - "java"
240 | - id: "find_sec_bugs.TRUST_BOUNDARY_VIOLATION-1"
241 | patterns:
242 | - pattern-either:
243 | - patterns:
244 | - pattern: "(HttpServletRequest $H). ... .setAttribute($ARG1, $ARG2);"
245 | - pattern-not: "(HttpServletRequest $H). ... .setAttribute(\"...\", \"...\");"
246 | - patterns:
247 | - pattern: "(HttpServletRequest $H). ... .putValue($ARG1, $ARG2);"
248 | - pattern-not: "(HttpServletRequest $H). ... .putValue(\"...\", \"...\");"
249 | languages:
250 | - "java"
251 | message: |
252 | A trust boundary can be thought of as line drawn through a program. On one side
253 | of the line, data is untrusted. On the other side of the line, data is assumed
254 | to be trustworthy. The purpose of validation logic is to allow data to safely
255 | cross the trust boundary - to move from untrusted to trusted. A trust boundary
256 | violation occurs when a program blurs the line between what is trusted and what
257 | is untrusted. By combining trusted and untrusted data in the same data
258 | structure, it becomes easier for programmers to mistakenly trust unvalidated
259 | data.
260 | metadata:
261 | category: "security"
262 | cwe: "CWE-501: Trust Boundary Violation"
263 | severity: "WARNING"
264 | - id: "find_sec_bugs.PERMISSIVE_CORS-1"
265 | patterns:
266 | - pattern-either:
267 | - pattern: "(HttpServletResponse $RES).setHeader(\"$HEADER\", \"$VAL\")"
268 | - pattern: "(HttpServletResponse $RES).addHeader(\"$HEADER\", \"$VAL\")"
269 | - metavariable-regex:
270 | metavariable: "$HEADER"
271 | regex: "(?i)(Access-Control-Allow-Origin)"
272 | - metavariable-regex:
273 | metavariable: "$VAL"
274 | regex: "(\\*|null)"
275 | message: |
276 | Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for
277 | JavaScript to access the contents of a Web page, both the JavaScript and the Web page must
278 | originate from the same domain. Without the Same Origin Policy, a malicious website could serve
279 | up JavaScript that loads sensitive information from other websites using a client's
280 | credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible
281 | for JavaScript to access data across domains if a new HTTP header called
282 | Access-Control-Allow-Origin is defined. With this header, a Web server defines which other
283 | domains are allowed to access its domain using cross-origin requests. However, caution should
284 | be taken when defining the header because an overly permissive CORS policy will allow a
285 | malicious application to communicate with the victim application in an inappropriate way,
286 | leading to spoofing, data theft, relay and other attacks.
287 | languages:
288 | - "java"
289 | severity: "ERROR"
290 | metadata:
291 | cwe: "CWE-942: Permissive Cross-domain Policy with Untrusted Domains"
292 | category: "security"
293 | technology:
294 | - "java"
295 | - id: "find_sec_bugs.PERMISSIVE_CORS-2"
296 | mode: "taint"
297 | pattern-sources:
298 | - pattern: "(HttpServletRequest $REQ).getParamater(...)"
299 | pattern-sinks:
300 | - patterns:
301 | - pattern-either:
302 | - pattern: "(HttpServletResponse $RES).setHeader(\"$HEADER\", ...)"
303 | - pattern: "(HttpServletResponse $RES).addHeader(\"$HEADER\", ...)"
304 | - metavariable-regex:
305 | metavariable: "$HEADER"
306 | regex: "(?i)(Access-Control-Allow-Origin)"
307 | message: |
308 | Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for
309 | JavaScript to access the contents of a Web page, both the JavaScript and the Web page must
310 | originate from the same domain. Without the Same Origin Policy, a malicious website could serve
311 | up JavaScript that loads sensitive information from other websites using a client's
312 | credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible
313 | for JavaScript to access data across domains if a new HTTP header called
314 | Access-Control-Allow-Origin is defined. With this header, a Web server defines which other
315 | domains are allowed to access its domain using cross-origin requests. However, caution should
316 | be taken when defining the header because an overly permissive CORS policy will allow a
317 | malicious application to communicate with the victim application in an inappropriate way,
318 | leading to spoofing, data theft, relay and other attacks.
319 | languages:
320 | - "java"
321 | severity: "ERROR"
322 | metadata:
323 | cwe: "CWE-942: Permissive Cross-domain Policy with Untrusted Domains"
324 | category: "security"
325 | technology:
326 | - "java"
327 | - id: "find_sec_bugs.BLOWFISH_KEY_SIZE-1"
328 | patterns:
329 | - pattern-inside: |
330 | $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...);
331 | ...
332 | $KEYGEN.init($KEY_SIZE);
333 | - metavariable-comparison:
334 | metavariable: "$KEY_SIZE"
335 | comparison: "$KEY_SIZE < 128"
336 | message: |
337 | A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of
338 | entropy should be used when generating the key if use of Blowfish is required.
339 | languages:
340 | - "java"
341 | severity: "WARNING"
342 | metadata:
343 | category: "security"
344 | cwe: "CWE-326: Inadequate Encryption Strength"
345 | technology:
346 | - "java"
347 | - id: "find_sec_bugs.DES_USAGE-1"
348 | patterns:
349 | - pattern-inside: |-
350 | javax.crypto.Cipher.getInstance("$ALG")
351 | - metavariable-regex:
352 | metavariable: "$ALG"
353 | regex: "^(DES)/.*"
354 | message: |
355 | DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage
356 | of AES block ciphers instead of DES.
357 | languages:
358 | - "java"
359 | severity: "WARNING"
360 | metadata:
361 | category: "security"
362 | cwe: "CWE-326: Inadequate Encryption Strength"
363 | technology:
364 | - "java"
365 | - id: "find_sec_bugs.TDES_USAGE-1"
366 | patterns:
367 | - pattern-inside: |-
368 | javax.crypto.Cipher.getInstance("$ALG")
369 | - metavariable-regex:
370 | metavariable: "$ALG"
371 | regex: "^(DESede)/.*"
372 | message: |
373 | Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern
374 | applications. NIST recommends the usage of AES block ciphers instead of 3DES.
375 | languages:
376 | - "java"
377 | severity: "WARNING"
378 | metadata:
379 | category: "security"
380 | cwe: "CWE-326: Inadequate Encryption Strength"
381 | technology:
382 | - "java"
383 | - id: "find_sec_bugs.ECB_MODE-1"
384 | patterns:
385 | - pattern-inside: |-
386 | javax.crypto.Cipher.getInstance("...")
387 | - pattern-regex: "(AES|DES(ede)?)(/ECB/*)"
388 | message: |
389 | An authentication cipher mode which provides better confidentiality of the encrypted data
390 | should be used instead of Electronic Code Book (ECB) mode, which does not provide good
391 | confidentiality. Specifically, ECB mode produces the same output for the same input each time.
392 | This allows an attacker to intercept and replay the data.
393 | languages:
394 | - "java"
395 | severity: "ERROR"
396 | metadata:
397 | category: "security"
398 | cwe: "CWE-326: Inadequate Encryption Strength"
399 | technology:
400 | - "java"
401 | - id: "find_sec_bugs.CIPHER_INTEGRITY-1"
402 | patterns:
403 | - pattern-inside: |-
404 | javax.crypto.Cipher.getInstance("...")
405 | - pattern-either:
406 | - pattern-regex: "(/CBC/PKCS5Padding)"
407 | - pattern-regex: "(AES|DES(ede)?)(/ECB/*)"
408 | - pattern-not-regex: ".*/(CCM|CWC|OCB|EAX|GCM)/.*"
409 | - pattern-not-regex: "^(RSA)/.*"
410 | - pattern-not-regex: "^(ECIES)$"
411 | message: |
412 | The ciphertext produced is susceptible to alteration by an adversary. This mean that the
413 | cipher provides no way to detect that the data has been tampered with. If the ciphertext can be
414 | controlled by an attacker, it could be altered without detection.
415 | languages:
416 | - "java"
417 | severity: "ERROR"
418 | metadata:
419 | category: "security"
420 | cwe: "CWE-353: Missing Support for Integrity Check"
421 | technology:
422 | - "java"
423 | - id: "find_sec_bugs.PADDING_ORACLE-1"
424 | patterns:
425 | - pattern-inside: |-
426 | javax.crypto.Cipher.getInstance("...")
427 | - pattern-regex: "(/CBC/PKCS5Padding)"
428 | - pattern-not-regex: "^(RSA)/.*"
429 | - pattern-not-regex: "^(ECIES)$"
430 | message: |
431 | This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An
432 | adversary could potentially decrypt the message if the system exposed the difference between
433 | plaintext with invalid padding or valid padding. The distinction between valid and invalid
434 | padding is usually revealed through distinct error messages being returned for each condition.
435 | languages:
436 | - "java"
437 | severity: "ERROR"
438 | metadata:
439 | category: "security"
440 | cwe: "CWE-696: Incorrect Behavior Order"
441 | technology:
442 | - "java"
443 | - id: "find_sec_bugs.CUSTOM_MESSAGE_DIGEST-1"
444 | patterns:
445 | - pattern: |
446 | class $CLAZZ extends java.security.MessageDigest {
447 | ...
448 | }
449 | message: |
450 | Implementing a custom MessageDigest is error-prone. National Institute of Standards and
451 | Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or
452 | SHA-512/256.
453 | languages:
454 | - "java"
455 | severity: "WARNING"
456 | metadata:
457 | category: "security"
458 | cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
459 | technology:
460 | - "java"
461 | - id: "find_sec_bugs.DEFAULT_HTTP_CLIENT-1"
462 | patterns:
463 | - pattern: "new org.apache.http.impl.client.DefaultHttpClient(...);"
464 | message: |
465 | DefaultHttpClient with default constructor is not compatible with TLS 1.2
466 | languages:
467 | - "java"
468 | severity: "WARNING"
469 | metadata:
470 | category: "security"
471 | technology:
472 | - "java"
473 | - id: "find_sec_bugs.HAZELCAST_SYMMETRIC_ENCRYPTION-1"
474 | patterns:
475 | - pattern: "new com.hazelcast.config.SymmetricEncryptionConfig()"
476 | message: |
477 | The network communications for Hazelcast is configured to use a symmetric cipher (probably DES
478 | or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of
479 | asymmetric encryption is preferred.
480 | languages:
481 | - "java"
482 | severity: "WARNING"
483 | metadata:
484 | category: "security"
485 | cwe: "CWE-326: Inadequate Encryption Strength"
486 | technology:
487 | - "java"
488 | - id: "find_sec_bugs.RSA_KEY_SIZE-1"
489 | patterns:
490 | - pattern-either:
491 | - patterns:
492 | - pattern-inside: |
493 | $GEN = KeyPairGenerator.getInstance($ALG, ...);
494 | ...
495 | - pattern-either:
496 | - pattern: "$VAR.initialize($SIZE, ...);"
497 | - pattern: "new java.security.spec.RSAKeyGenParameterSpec($SIZE,...);"
498 | - metavariable-comparison:
499 | metavariable: "$SIZE"
500 | comparison: "$SIZE < 2048"
501 | - metavariable-regex:
502 | metavariable: "$ALG"
503 | regex: "\"(RSA|DSA)\""
504 | message: |
505 | Detected an insufficient key size for DSA. NIST recommends a key size
506 | of 2048 or higher.
507 | metadata:
508 | category: "security"
509 | cwe: "CWE-326: Inadequate Encryption Strength"
510 | severity: "WARNING"
511 | languages:
512 | - "java"
513 | - id: "find_sec_bugs.NULL_CIPHER-1"
514 | pattern: "new javax.crypto.NullCipher()"
515 | message: |
516 | The NullCipher implements the Cipher interface by returning ciphertext identical to the
517 | supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid
518 | using the NullCipher. Its accidental use can introduce a significant confidentiality risk.
519 | languages:
520 | - "java"
521 | severity: "WARNING"
522 | metadata:
523 | category: "security"
524 | cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
525 | technology:
526 | - "java"
527 | - id: "find_sec_bugs.RSA_NO_PADDING-1"
528 | patterns:
529 | - pattern: "javax.crypto.Cipher.getInstance($ALG,...);"
530 | - metavariable-regex:
531 | metavariable: "$ALG"
532 | regex: ".*NoPadding.*"
533 | message: |
534 | The software uses the RSA algorithm but does not incorporate Optimal Asymmetric
535 | Encryption Padding (OAEP), which might weaken the encryption.
536 | metadata:
537 | cwe: "CWE-780: Use of RSA Algorithm without OAEP"
538 | severity: "WARNING"
539 | languages:
540 | - "java"
541 | - id: "find_sec_bugs.WEAK_MESSAGE_DIGEST_MD5-1.WEAK_MESSAGE_DIGEST_SHA1-1"
542 | patterns:
543 | - pattern-either:
544 | - pattern: "MessageDigest.getInstance($ALG, ...)"
545 | - pattern: "Signature.getInstance($ALG, ...)"
546 | - metavariable-regex:
547 | metavariable: "$ALG"
548 | regex: ".*(MD5|MD4|MD2|SHA1|SHA-1).*"
549 | message: |
550 | DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage
551 | of AES block ciphers instead of DES.
552 | languages:
553 | - "java"
554 | severity: "WARNING"
555 | metadata:
556 | category: "security"
557 | cwe: "CWE-326: Inadequate Encryption Strength"
558 | technology:
559 | - "java"
560 | - id: "find_sec_bugs.SSL_CONTEXT-1"
561 | patterns:
562 | - pattern-either:
563 | - pattern: "new org.apache.http.impl.client.DefaultHttpClient();"
564 | - pattern: "javax.net.ssl.SSLContext.getInstance(\"SSL\");"
565 | message: |
566 | A HostnameVerifier that accept any host are often use because of certificate
567 | reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks
568 | attacks since the client will trust any certificate.
569 | metadata:
570 | category: "security"
571 | cwe: "CWE-295: Improper Certificate Validation"
572 | severity: "WARNING"
573 | languages:
574 | - "java"
575 | - id: "find_sec_bugs.SERVLET_PARAMETER-1.SERVLET_CONTENT_TYPE-1.SERVLET_SERVER_NAME-1.SERVLET_SESSION_ID-1.SERVLET_QUERY_STRING-1.SERVLET_HEADER-1.SERVLET_HEADER_REFERER-1.SERVLET_HEADER_USER_AGENT-1"
576 | mode: "taint"
577 | pattern-sources:
578 | - pattern-either:
579 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getContentType(...)"
580 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getServerName(...)"
581 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getRequestedSessionId(...)"
582 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameterValues(...)"
583 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameterMap(...)"
584 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameterNames(...)"
585 | - pattern: "(javax.servlet.http.HttpServletRequest $REQ).getParameter(...)"
586 | pattern-sinks:
587 | - pattern-either:
588 | - pattern: "\"...\" + $PAR"
589 | - pattern: "$PAR + \"...\""
590 | languages:
591 | - "java"
592 | message: |
593 | The Servlet can read GET and POST parameters from various methods. The
594 | value obtained should be considered unsafe."
595 | metadata:
596 | category: "security"
597 | cwe: "CWE-20: Improper Input Validation"
598 | severity: "WARNING"
599 | - id: "find_sec_bugs.JAXRS_ENDPOINT-1"
600 | mode: "taint"
601 | pattern-sources:
602 | - patterns:
603 | - pattern-inside: |
604 | @javax.ws.rs.Path("...")
605 | $TYPE $FUNC(..., $VAR, ...) {
606 | ...
607 | }
608 | - pattern: "$VAR"
609 | pattern-sanitizers:
610 | - patterns:
611 | - pattern-inside: |
612 | $STR.replaceAll("$REPLACE_CHAR", "$REPLACER");
613 | ...
614 | - pattern: "$STR"
615 | - metavariable-regex:
616 | metavariable: "$REPLACER"
617 | regex: ".*^(CRLF).*"
618 | - metavariable-regex:
619 | metavariable: "$REPLACE_CHAR"
620 | regex: "(*CRLF)"
621 | - pattern: "org.apache.commons.text.StringEscapeUtils.unescapeJava(...);"
622 | pattern-sinks:
623 | - pattern: "return ...;"
624 | message: |
625 | This method is part of a REST Web Service (JSR311). The security of this web service should be
626 | analyzed; Authentication, if enforced, should be tested. Access control, if enforced, should be
627 | tested. The inputs should be tracked for potential vulnerabilities. The communication should
628 | ideally be over SSL.
629 | languages:
630 | - "java"
631 | severity: "WARNING"
632 | metadata:
633 | category: "security"
634 | cwe: "CWE-20: Improper Input Validation"
635 | technology:
636 | - "java"
637 | - id: "find_sec_bugs.JAXWS_ENDPOINT-1"
638 | mode: "taint"
639 | pattern-sources:
640 | - patterns:
641 | - pattern-inside: |
642 | @javax.jws.WebMethod(...)
643 | $TYPE $FUNC(..., $VAR, ...) {
644 | ...
645 | }
646 | - pattern: "$VAR"
647 | pattern-sanitizers:
648 | - patterns:
649 | - pattern-inside: |
650 | $STR.replaceAll("$REPLACE_CHAR", "$REPLACER");
651 | ...
652 | - pattern: "$STR"
653 | - metavariable-regex:
654 | metavariable: "$REPLACER"
655 | regex: ".*^(CRLF).*"
656 | - metavariable-regex:
657 | metavariable: "$REPLACE_CHAR"
658 | regex: "(*CRLF)"
659 | - pattern: "org.apache.commons.text.StringEscapeUtils.unescapeJava(...);"
660 | pattern-sinks:
661 | - pattern: "return ...;"
662 | message: |
663 | This method is part of a SOAP Web Service (JSR224). The security of this web service should be
664 | analyzed; Authentication, if enforced, should be tested. Access control, if enforced, should be
665 | tested. The inputs should be tracked for potential vulnerabilities. The communication should
666 | ideally be over SSL.
667 | languages:
668 | - "java"
669 | severity: "INFO"
670 | metadata:
671 | category: "security"
672 | cwe: "CWE-20: Improper Input Validation"
673 | owasp: "OWASP: Cross-Site Request Forgery"
674 | technology:
675 | - "java"
676 | - id: "find_sec_bugs.UNENCRYPTED_SOCKET-1.UNENCRYPTED_SERVER_SOCKET-1"
677 | patterns:
678 | - pattern: "new java.net.Socket(...)"
679 | languages:
680 | - "java"
681 | message: |
682 | Beyond using an SSL socket, you need to make sure your use of SSLSocketFactory
683 | does all the appropriate certificate validation checks to make sure you are not
684 | subject to man-in-the-middle attacks. Please read the OWASP Transport Layer
685 | Protection Cheat Sheet for details on how to do this correctly.
686 | metadata:
687 | cwe: "CWE-319: Cleartext Transmission of Sensitive Information"
688 | severity: "WARNING"
689 | - id: "find_sec_bugs.UNVALIDATED_REDIRECT-1.URL_REWRITING-1"
690 | patterns:
691 | - pattern-either:
692 | - patterns:
693 | - pattern: "(HttpServletResponse $REQ).sendRedirect(...)"
694 | - pattern-not: "(HttpServletResponse $REQ).sendRedirect(\"...\")"
695 | - patterns:
696 | - pattern: "(HttpServletResponse $REQ).addHeader(...)"
697 | - pattern-not: "(HttpServletResponse $REQ).addHeader(\"...\", \"...\")"
698 | - patterns:
699 | - pattern: "(HttpServletResponse $REQ).encodeURL(...)"
700 | - pattern-not: "(HttpServletResponse $REQ).encodeURL(\"...\")"
701 | - patterns:
702 | - pattern: "(HttpServletResponse $REQ).encodeRedirectUrl(...)"
703 | - pattern-not: "(HttpServletResponse $REQ).encodeRedirectUrl(\"...\")"
704 | languages:
705 | - "java"
706 | message: |
707 | Unvalidated redirects occur when an application redirects a user to a
708 | destination URL specified by a user supplied parameter that is not validated.
709 | Such vulnerabilities can be used to facilitate phishing attacks.
710 | metadata:
711 | category: "security"
712 | cwe: "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')"
713 | severity: "ERROR"
714 | - id: "find_sec_bugs.WEAK_HOSTNAME_VERIFIER-1.WEAK_TRUST_MANAGER-1"
715 | patterns:
716 | - pattern-either:
717 | - patterns:
718 | - pattern-inside: |
719 | class $V implements HostnameVerifier {
720 | ...
721 | }
722 | - pattern-inside: |
723 | public boolean verify(...) {
724 | ...
725 | }
726 | - pattern: "return true;"
727 | - patterns:
728 | - pattern-inside: |
729 | class $V implements X509TrustManager {
730 | ...
731 | }
732 | - pattern-either:
733 | - pattern: "public void checkClientTrusted(...) {}"
734 | - pattern: "public void checkServerTrusted(...) {}"
735 | - pattern: |
736 | public X509Certificate[] getAcceptedIssuers() {
737 | ...
738 | return null;
739 | }
740 | languages:
741 | - "java"
742 | message: |
743 | A HostnameVerifier that accept any host are often use because of certificate
744 | reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle
745 | attacks since the client will trust any certificate.
746 | metadata:
747 | category: "security"
748 | cwe: "CWE-295: Improper Certificate Validation"
749 | severity: "WARNING"
750 | - id: "find_sec_bugs.FILE_UPLOAD_FILENAME-1"
751 | patterns:
752 | - pattern-inside: |
753 | $FUNC(..., HttpServletRequest $REQ, ... ) {
754 | ...
755 | $FILES = (ServletFileUpload $SFU).parseRequest($REQ);
756 | ...
757 | }
758 | - pattern-inside: |
759 | for(FileItem $ITEM : $FILES) {
760 | ...
761 | }
762 | - pattern: "$ITEM.getName()"
763 | message: |
764 | The filename provided by the FileUpload API can be tampered with by the client to reference
765 | unauthorized files. The provided filename should be properly validated to ensure it's properly
766 | structured, contains no unauthorized path characters (e.g., / \), and refers to an authorized
767 | file.
768 | languages:
769 | - "java"
770 | severity: "ERROR"
771 | metadata:
772 | category: "security"
773 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
774 | Traversal')"
775 | technology:
776 | - "java"
777 | - id: "find_sec_bugs.WEAK_FILENAMEUTILS-1"
778 | patterns:
779 | - pattern-inside: |
780 | import static org.apache.commons.io.FilenameUtils;
781 | ...
782 | - pattern-either:
783 | - pattern: "normalize(...)"
784 | - pattern: "getExtension(...)"
785 | - pattern: "isExtensions(...)"
786 | - pattern: "getName(...)"
787 | - pattern: "getBaseName(...)"
788 | - pattern: "org.apache.commons.io.FilenameUtils.normalize(...)"
789 | - pattern: "org.apache.commons.io.FilenameUtils.getExtension(...)"
790 | - pattern: "org.apache.commons.io.FilenameUtils.isExtensions(...)"
791 | - pattern: "org.apache.commons.io.FilenameUtils.getName(...)"
792 | - pattern: "org.apache.commons.io.FilenameUtils.getBaseName(...)"
793 | message: |
794 | A file is opened to read its content. The filename comes from an input
795 | parameter. If an unfiltered parameter is passed to this file API, files from an
796 | arbitrary filesystem location could be read.
797 | languages:
798 | - "java"
799 | severity: "ERROR"
800 | metadata:
801 | category: "security"
802 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
803 | Traversal')"
804 | technology:
805 | - "java"
806 | - id: "find_sec_bugs.STRUTS_FORM_VALIDATION-1"
807 | patterns:
808 | - pattern-inside: |
809 | class $CLASS extends $SC {
810 | ...
811 | }
812 | - metavariable-regex:
813 | metavariable: "$SC"
814 | regex: "(ActionForm|ValidatorForm)"
815 | - pattern-not: "public void validate() { ... }"
816 | languages:
817 | - "java"
818 | message: |
819 | Form inputs should have minimal input validation. Preventive validation helps
820 | provide defense in depth against a variety of risks.
821 | metadata:
822 | category: "security"
823 | cwe: "CWE-20: Improper Input Validation"
824 | severity: "WARNING"
825 | - id: "find_sec_bugs.AWS_QUERY_INJECTION-1"
826 | mode: "taint"
827 | pattern-sources:
828 | - patterns:
829 | - pattern-inside: |
830 | $FUNC(..., $VAR, ...) {
831 | ...
832 | }
833 | - pattern: "$VAR"
834 | - patterns:
835 | - pattern-inside: |
836 | $FUNC(...) {
837 | ...
838 | $VAR = ... + $X;
839 | ...
840 | }
841 | - pattern: "$VAR"
842 | pattern-sinks:
843 | - patterns:
844 | - pattern-either:
845 | - pattern-inside: |
846 | $REQ = new SelectRequest($QUERY, ...);
847 | ...
848 | $DB.select($REQ);
849 | - pattern-inside: |
850 | $DB.select(new SelectRequest($QUERY,...));
851 | - pattern-inside: |
852 | $DB.select((SelectRequest $SR).withSelectExpression($QUERY,...));
853 | - pattern: "$QUERY"
854 | - metavariable-pattern:
855 | metavariable: "$DB"
856 | pattern-either:
857 | - pattern: "(AmazonSimpleDB $DB)"
858 | - pattern: "(AmazonSimpleDBClient $DB)"
859 | message: |
860 | Constructing SimpleDB queries containing user input can allow an attacker to view unauthorized
861 | records.
862 | languages:
863 | - "java"
864 | severity: "ERROR"
865 | metadata:
866 | category: "security"
867 | cwe: "CWE-943: Improper Neutralization of Special Elements in Data Query Logic"
868 | technology:
869 | - "java"
870 | - id: "find_sec_bugs.BEAN_PROPERTY_INJECTION-1"
871 | patterns:
872 | - pattern-inside: |-
873 | $TYPE $FUNC(..., HttpServletRequest $REQ, ...) { ... }
874 | - pattern-either:
875 | - pattern: |
876 | $MAP.put(..., $REQ.getParameter(...));
877 | ...
878 | $BEAN_UTIL.populate(..., $MAP);
879 | - pattern: |
880 | while (...) {
881 | ...
882 | $MAP.put(..., $REQ.getParameterValues(...));
883 | }
884 | ...
885 | $BEAN_UTIL.populate(..., $MAP);
886 | - metavariable-pattern:
887 | metavariable: "$BEAN_UTIL"
888 | pattern-either:
889 | - pattern: "(BeanUtilsBean $B)"
890 | - pattern: "new BeanUtilsBean()"
891 | - pattern: "org.apache.commons.beanutils.BeanUtils"
892 | message: |
893 | An attacker can set arbitrary bean properties that can compromise system integrity. An
894 | attacker can leverage this functionality to access special bean properties like
895 | class.classLoader that will allow them to override system properties and potentially execute
896 | arbitrary code.
897 | languages:
898 | - "java"
899 | severity: "ERROR"
900 | metadata:
901 | category: "security"
902 | cwe: "CWE-15: External Control of System or Configuration Setting"
903 | technology:
904 | - "java"
905 | - id: "find_sec_bugs.CRLF_INJECTION_LOGS-1"
906 | patterns:
907 | - pattern-either:
908 | - pattern: |
909 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
910 | ...
911 | $LOGGER.$METHOD(...,$TAINTED,...);
912 | - pattern: |
913 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
914 | ...
915 | $VAR = String.Format(..., $TAINTED,...);
916 | ...
917 | $LOGGER.$METHOD(...,$VAR,...);
918 | - pattern: |
919 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
920 | ...
921 | $LOGGER.$METHOD(...,String.Format(..., $TAINTED,...),...);
922 | - pattern: |
923 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
924 | ...
925 | $VAR = ... + $TAINTED + ...;
926 | ...
927 | $LOGGER.$METHOD(...,$VAR,...);
928 | - pattern: |
929 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
930 | ...
931 | $LOGGER.$METHOD(...,... + $TAINTED + ...,...);
932 | - metavariable-regex:
933 | metavariable: "$METHOD"
934 | regex: "(log|logp|logrb|entering|exiting|fine|finer|finest|info|debug|trace|warn|warning|config|error|severe)"
935 | - metavariable-pattern:
936 | metavariable: "$LOGGER"
937 | pattern-either:
938 | - pattern: "(Logger $LOG)"
939 | - pattern: "org.pmw.tinylog.Logger"
940 | - pattern: "org.apache.log4j.Logger"
941 | - pattern: "org.apache.logging.log4j.Logger"
942 | - pattern: "org.slf4j.Logger"
943 | - pattern: "org.apache.commons.logging.Log"
944 | - pattern: "java.util.logging.Logger"
945 | message: |
946 | When data from an untrusted source is put into a logger and not neutralized correctly, an
947 | attacker could forge log entries or include malicious content. Inserted false entries could be
948 | used to skew statistics, distract the administrator or even to implicate another party in the
949 | commission of a malicious act. If the log file is processed automatically, the attacker can
950 | render the file unusable by corrupting the format of the file or injecting unexpected
951 | characters. An attacker may also inject code or other commands into the log file and take
952 | advantage of a vulnerability in the log processing utility (e.g. command injection or XSS).
953 | languages:
954 | - "java"
955 | severity: "ERROR"
956 | metadata:
957 | category: "security"
958 | cwe: "CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')"
959 | technology:
960 | - "java"
961 | - id: "find_sec_bugs.COMMAND_INJECTION-1"
962 | pattern-either:
963 | - patterns:
964 | - pattern-inside: |
965 | $FUNC(...,String $PARAM, ...) {
966 | ...
967 | }
968 | - pattern-either:
969 | - pattern: "(Runtime $R).exec($PARAM,...);"
970 | - patterns:
971 | - pattern-either:
972 | - pattern: |
973 | $CMDARR = new String[]{"$SHELL",...,$PARAM,...};
974 | ...
975 | (Runtime $R).exec($CMDARR,...);
976 | - pattern: "(Runtime $R).exec(new String[]{\"$SHELL\",...,$PARAM,...}, ...);"
977 | - pattern: "(Runtime $R).exec(java.util.String.format(\"...\", ...,$PARAM,...));"
978 | - pattern: "(Runtime $R).exec((String $A) + (String $B));"
979 | - metavariable-regex:
980 | metavariable: "$SHELL"
981 | regex: "(/.../)?(sh|bash|ksh|csh|tcsh|zsh)$"
982 | - pattern-not: "(Runtime $R).exec(\"...\",\"...\",\"...\",...);"
983 | - pattern-not: "(Runtime $R).exec(new String[]{\"...\",\"...\",\"...\",...},...);\n"
984 | - patterns:
985 | - pattern-inside: |
986 | $FUNC(...,String $PARAM, ...) {
987 | ...
988 | }
989 | - pattern-either:
990 | - pattern: "(ProcessBuilder $PB).command($PARAM,...);"
991 | - patterns:
992 | - pattern-either:
993 | - pattern: "(ProcessBuilder $PB).command(\"$SHELL\",...,$PARAM,...);"
994 | - pattern: |
995 | $CMDARR = java.util.Arrays.asList("$SHELL",...,$PARAM,...);
996 | ...
997 | (ProcessBuilder $PB).command($CMDARR,...);
998 | - pattern: "(ProcessBuilder $PB).command(java.util.Arrays.asList(\"$SHELL\",...,$PARAM,...),...);"
999 | - pattern: "(ProcessBuilder $PB).command(java.util.String.format(\"...\",
1000 | ...,$PARAM,...));"
1001 | - pattern: "(ProcessBuilder $PB).command((String $A) + (String $B));"
1002 | - metavariable-regex:
1003 | metavariable: "$SHELL"
1004 | regex: "(/.../)?(sh|bash|ksh|csh|tcsh|zsh)$"
1005 | - pattern-not: "(ProcessBuilder $PB).command(\"...\",\"...\",\"...\",...);"
1006 | - pattern-not: "(ProcessBuilder $PB).command(java.util.Arrays.asList(\"...\",\"...\",\"...\",...));\n"
1007 | message: |
1008 | The highlighted API is used to execute a system command. If unfiltered input is passed to this
1009 | API, it can lead to arbitrary command execution.
1010 | languages:
1011 | - "java"
1012 | severity: "WARNING"
1013 | metadata:
1014 | category: "security"
1015 | cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command
1016 | ('OS Command Injection')"
1017 | technology:
1018 | - "java"
1019 | - id: "find_sec_bugs.CUSTOM_INJECTION-1"
1020 | patterns:
1021 | - pattern-either:
1022 | - pattern: |
1023 | $QUERY = ... + $VAR + ...;
1024 | ...
1025 | $ST.executeQuery($QUERY);
1026 | - pattern: |
1027 | $QUERY = ... + $VAR ;
1028 | ...
1029 | $ST.executeQuery($QUERY);
1030 | - pattern: |
1031 | $QUERY = String.format("...",...,$VAR,...);
1032 | ...
1033 | $ST.executeQuery($QUERY);
1034 | - pattern: "$ST.executeQuery((StringBuilder $SB).toString());"
1035 | - pattern: "$ST.executeQuery(... + $VAR + ...);"
1036 | - pattern: "$ST.executeQuery(... + $VAR);"
1037 | - pattern: "$ST.executeQuery(...,String.format(\"...\",...,$VAR,...), ...);"
1038 | - metavariable-pattern:
1039 | metavariable: "$ST"
1040 | pattern-either:
1041 | - pattern: "(java.sql.Statement $ST)"
1042 | - pattern: "(org.apache.turbine.om.peer.BasePeer $ST)"
1043 | message: |
1044 | The method identified is susceptible to injection. The input should be validated and properly
1045 | escaped.
1046 | languages:
1047 | - "java"
1048 | severity: "WARNING"
1049 | metadata:
1050 | category: "security"
1051 | cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command
1052 | ('SQL Injection')"
1053 | technology:
1054 | - "java"
1055 | - id: "find_sec_bugs.CUSTOM_INJECTION-2"
1056 | patterns:
1057 | - pattern-either:
1058 | - pattern: |
1059 | "$SQL_STR" + ...
1060 | - pattern: "String.format(\"$SQL_STR\", ...)"
1061 | - pattern: |
1062 | "$SQL_STR".concat(...)
1063 | - pattern: "(StringBuilder $BUILDER). ... .append(\"$SQL_STR\")"
1064 | - patterns:
1065 | - pattern-inside: |
1066 | StringBuilder $BUILDER = new StringBuilder("$SQL_STR");
1067 | ...
1068 | - pattern: "$BUILDER.append(...)"
1069 | - patterns:
1070 | - pattern-inside: |
1071 | $QUERY = "$SQL_STR";
1072 | ...
1073 | - pattern: "$QUERY += ..."
1074 | - metavariable-regex:
1075 | metavariable: "$SQL_STR"
1076 | regex: "(?i)(select|insert|create|update|alter|delete|drop)\\b"
1077 | message: |
1078 | The method identified is susceptible to injection. The input should be validated and properly
1079 | escaped.
1080 | languages:
1081 | - "java"
1082 | severity: "WARNING"
1083 | metadata:
1084 | category: "security"
1085 | cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command
1086 | ('SQL Injection')"
1087 | technology:
1088 | - "java"
1089 | - id: "find_sec_bugs.EL_INJECTION-1"
1090 | patterns:
1091 | - pattern-inside: |
1092 | $FUNC(..., String $EXPR, ...) {
1093 | ...
1094 | ELContext $CTX = ...;
1095 | ...
1096 | }
1097 | - pattern-either:
1098 | - pattern: "(ExpressionFactory $EXP).createValueExpression((ELContext $CTX), $EXPR,
1099 | ...)"
1100 | - pattern: "(ExpressionFactory $EXP).createMethodExpression((ELContext $CTX),
1101 | $EXPR, ...)"
1102 | message: |
1103 | An expression is built with a dynamic value. The source of the value(s) should be verified to
1104 | avoid that unfiltered values fall into this risky code evaluation.
1105 | languages:
1106 | - "java"
1107 | severity: "WARNING"
1108 | metadata:
1109 | category: "security"
1110 | cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
1111 | technology:
1112 | - "java"
1113 | - id: "find_sec_bugs.REQUESTDISPATCHER_FILE_DISCLOSURE-1.STRUTS_FILE_DISCLOSURE-1.SPRING_FILE_DISCLOSURE-1"
1114 | mode: "taint"
1115 | pattern-sources:
1116 | - pattern: "(javax.servlet.http.HttpServletRequest $VAR).getParameter(...)"
1117 | pattern-sinks:
1118 | - patterns:
1119 | - pattern: "new org.springframework.web.servlet.ModelAndView($FST);"
1120 | - pattern: "$FST"
1121 | - patterns:
1122 | - pattern: "new org.springframework.web.servlet.ModelAndView($FST, $SND);"
1123 | - pattern: "$FST"
1124 | - patterns:
1125 | - pattern: "new org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD);"
1126 | - pattern: "$FST"
1127 | - patterns:
1128 | - pattern: "new org.apache.struts.action.ActionForward($FST)"
1129 | - pattern: "$FST"
1130 | - patterns:
1131 | - pattern: "new org.apache.struts.action.ActionForward($FST, $SND)"
1132 | - pattern: "$FST"
1133 | - patterns:
1134 | - pattern: "new org.apache.struts.action.ActionForward($FST, $SND, $TRD)"
1135 | - pattern: "$SND"
1136 | - patterns:
1137 | - pattern: "new org.apache.struts.action.ActionForward($FST, $SND, $TRD)"
1138 | - pattern: "$TRD"
1139 | - patterns:
1140 | - pattern-inside: |
1141 | $ACTION = new org.apache.struts.action.ActionForward();
1142 | ...
1143 | - pattern: "$ACTION.setPath(...)"
1144 | - patterns:
1145 | - pattern-inside: |
1146 | $MVC = new org.springframework.web.servlet.ModelAndView();
1147 | ...
1148 | - pattern: "$MVC.setViewName(...);"
1149 | - patterns:
1150 | - pattern-inside: |
1151 | $REQ = $HTTP.getRequestDispatcher(...);
1152 | ...
1153 | - pattern-either:
1154 | - pattern: "$REQ.include($FST, $SND)"
1155 | - pattern: "$REQ.forward($FST, $SND)"
1156 | languages:
1157 | - "java"
1158 | message: |
1159 | Constructing a server-side redirect path with user input could allow an
1160 | attacker to download application binaries (including application classes or
1161 | jar files) or view arbitrary files within protected directories.
1162 | metadata:
1163 | category: "security"
1164 | cwe: "CWE-552: Files or Directories Accessible to External Parties"
1165 | severity: "ERROR"
1166 | - id: "find_sec_bugs.HTTP_PARAMETER_POLLUTION-1"
1167 | mode: "taint"
1168 | pattern-sources:
1169 | - pattern: "(HttpServletRequest $REQ).getParameter(...)"
1170 | pattern-sanitizers:
1171 | - pattern: "java.net.URLEncoder.encode(...)"
1172 | - pattern: "com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...)"
1173 | pattern-sinks:
1174 | - pattern: "new org.apache.http.client.methods.HttpGet(...)"
1175 | - pattern: "new org.apache.commons.httpclient.methods.GetMethod(...)"
1176 | - pattern: "(org.apache.commons.httpclient.methods.GetMethod $GM).setQueryString(...)"
1177 | message: |
1178 | Concatenating unvalidated user input into a URL can allow an attacker to override the value of
1179 | a request parameter. Attacker may be able to override existing parameter values, inject a new
1180 | parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks
1181 | consist of injecting encoded query string delimiters into other existing parameters. If a web
1182 | application does not properly sanitize the user input, a malicious user may compromise the
1183 | logic of the application to perform either client-side or server-side attacks.
1184 | languages:
1185 | - "java"
1186 | severity: "ERROR"
1187 | metadata:
1188 | category: "security"
1189 | cwe: "CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument
1190 | Injection')"
1191 | technology:
1192 | - "java"
1193 | - id: "find_sec_bugs.LDAP_INJECTION-1"
1194 | mode: "taint"
1195 | pattern-sources:
1196 | - patterns:
1197 | - pattern-inside: |
1198 | $FUNC(..., $VAR, ...) {
1199 | ...
1200 | }
1201 | - pattern: "$VAR"
1202 | - patterns:
1203 | - pattern-inside: |
1204 | $FUNC(..., $X, ...) {
1205 | ...
1206 | $VAR = ... + $X;
1207 | ...
1208 | }
1209 | - pattern: "$VAR"
1210 | pattern-sinks:
1211 | - pattern: "javax.naming.ldap.LdapName(...)"
1212 | - pattern: "(javax.naming.directory.Context $C).lookup(...)"
1213 | - pattern: "(javax.naming.Context $C).lookup(...)"
1214 | - patterns:
1215 | - pattern-inside: |-
1216 | (java.util.Properties $P).put($KEY, $VAL)
1217 | - pattern-not-inside: |
1218 | $FUNC(..., $VAL, ...) {
1219 | ...
1220 | }
1221 | - pattern: "$VAL"
1222 | - patterns:
1223 | - pattern-inside: |-
1224 | (com.unboundid.ldap.sdk.LDAPConnection $C).search($QUERY, ...)
1225 | - pattern: "$QUERY"
1226 | - patterns:
1227 | - pattern-either:
1228 | - pattern: "$CTX.lookup(...)"
1229 | - patterns:
1230 | - pattern-inside: |-
1231 | $CTX.search($QUERY, ...)
1232 | - pattern: "$QUERY"
1233 | - patterns:
1234 | - pattern-inside: |-
1235 | $CTX.search($NAME, $FILTER, ...)
1236 | - pattern: "$FILTER"
1237 | - metavariable-pattern:
1238 | metavariable: "$CTX"
1239 | pattern-either:
1240 | - pattern: "(javax.naming.directory.DirContext $C)"
1241 | - pattern: "(javax.naming.directory.InitialDirContext $IDC)"
1242 | - pattern: "(javax.naming.ldap.LdapContext $LC)"
1243 | - pattern: "(javax.naming.event.EventDirContext $EDC)"
1244 | - pattern: "(com.sun.jndi.ldap.LdapCtx $LC)"
1245 | - patterns:
1246 | - pattern-either:
1247 | - patterns:
1248 | - pattern-inside: |-
1249 | $CTX.list($QUERY, ...)
1250 | - pattern: "$QUERY"
1251 | - patterns:
1252 | - pattern-inside: |-
1253 | $CTX.lookup($QUERY, ...)
1254 | - pattern: "$QUERY"
1255 | - patterns:
1256 | - pattern-inside: |-
1257 | $CTX.search($QUERY, ...)
1258 | - pattern: "$QUERY"
1259 | - patterns:
1260 | - pattern-inside: |-
1261 | $CTX.search($NAME, $FILTER, ...)
1262 | - pattern: "$FILTER"
1263 | - metavariable-pattern:
1264 | metavariable: "$CTX"
1265 | pattern-either:
1266 | - pattern: "(org.springframework.ldap.core.LdapTemplate $LT)"
1267 | - pattern: "(org.springframework.ldap.core.LdapOperations $LO)"
1268 | message: |
1269 | Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately,
1270 | LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense
1271 | against LDAP injection is strong input validation of any untrusted data before including it in
1272 | an LDAP query.
1273 | languages:
1274 | - "java"
1275 | severity: "WARNING"
1276 | metadata:
1277 | category: "security"
1278 | cwe: "CWE-90: Improper Neutralization of Special Elements used in an LDAP Query
1279 | ('LDAP Injection')"
1280 | technology:
1281 | - "java"
1282 | - id: "find_sec_bugs.OGNL_INJECTION-1"
1283 | mode: "taint"
1284 | pattern-sources:
1285 | - patterns:
1286 | - pattern-inside: |
1287 | $FUNC(..., $VAR, ...) {
1288 | ...
1289 | }
1290 | - metavariable-pattern:
1291 | metavariable: "$VAR"
1292 | pattern-either:
1293 | - pattern: "(String $S)"
1294 | - pattern: "(Map $M)"
1295 | - pattern: "(Map $M)"
1296 | - pattern: "(Map $M)"
1297 | - pattern: "$VAR"
1298 | pattern-sinks:
1299 | - patterns:
1300 | - pattern-inside: |-
1301 | com.opensymphony.xwork2.util.TextParseUtil.translateVariables($VAL, ...)
1302 | - pattern: "$VAL"
1303 | - patterns:
1304 | - pattern-inside: |-
1305 | com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection($VAL, ...)
1306 | - pattern: "$VAL"
1307 | - pattern: "com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(...)"
1308 | - pattern: "com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(...)"
1309 | - patterns:
1310 | - pattern-inside: |-
1311 | (com.opensymphony.xwork2.util.TextParser $P).evaluate($VAR, $VAL, ...)
1312 | - pattern: "$VAL"
1313 | - patterns:
1314 | - pattern-inside: |-
1315 | (com.opensymphony.xwork2.util.OgnlTextParser $P).evaluate($VAR, $VAL, ...)
1316 | - pattern: "$VAL"
1317 | - pattern: "(com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getGetMethod($CLZ,
1318 | ...)"
1319 | - pattern: "(com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getSetMethod($CLZ,
1320 | ...)"
1321 | - pattern: "(com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getField($CLZ,
1322 | ...)"
1323 | - patterns:
1324 | - pattern-inside: |-
1325 | (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperties($MAP, ...)
1326 | - pattern: "$MAP"
1327 | - patterns:
1328 | - pattern-inside: |-
1329 | (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperty($VAL, ...)
1330 | - pattern: "$VAL"
1331 | - patterns:
1332 | - pattern-inside: |-
1333 | (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getValue($VAL, ...)
1334 | - pattern: "$VAL"
1335 | - patterns:
1336 | - pattern-inside: |-
1337 | (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setValue($VAL, ...)
1338 | - pattern: "$VAL"
1339 | - pattern: "(com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getGetMethod($CLZ,
1340 | ...)"
1341 | - pattern: "(com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getSetMethod($CLZ,
1342 | ...)"
1343 | - pattern: "(com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getField($CLZ,
1344 | ...)"
1345 | - patterns:
1346 | - pattern-inside: |-
1347 | (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperties($MAP, ...)
1348 | - pattern: "$MAP"
1349 | - patterns:
1350 | - pattern-inside: |-
1351 | (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperty($VAR, ...)
1352 | - pattern: "$VAR"
1353 | - patterns:
1354 | - pattern-inside: |-
1355 | (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getValue($VAR, ...)
1356 | - pattern: "$VAR"
1357 | - patterns:
1358 | - pattern-inside: |-
1359 | (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setValue($VAR, ...)
1360 | - pattern: "$VAR"
1361 | - patterns:
1362 | - pattern-inside: |-
1363 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperties($MAP, ...)
1364 | - pattern: "$MAP"
1365 | - patterns:
1366 | - pattern-inside: |-
1367 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperty($VAR, ...)
1368 | - pattern: "$VAR"
1369 | - patterns:
1370 | - pattern-inside: |-
1371 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).getValue($VAR, ...)
1372 | - pattern: "$VAR"
1373 | - patterns:
1374 | - pattern-inside: |-
1375 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).setValue($VAR, ...)
1376 | - pattern: "$VAR"
1377 | - patterns:
1378 | - pattern-inside: |-
1379 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).callMethod($VAR, ...)
1380 | - pattern: "$VAR"
1381 | - patterns:
1382 | - pattern-inside: |-
1383 | (com.opensymphony.xwork2.ognl.OgnlUtil $P).compile($VAR, ...)
1384 | - pattern: "$VAR"
1385 | - pattern: "(org.apache.struts2.util.VelocityStrutsUtil $P).evaluate(...)"
1386 | - pattern: "org.apache.struts2.util.StrutsUtil.findString(...)"
1387 | - pattern: "org.apache.struts2.util.StrutsUtil.findValue(..., $VAL)"
1388 | - pattern: "org.apache.struts2.util.StrutsUtil.getText(...)"
1389 | - pattern: "org.apache.struts2.util.StrutsUtil.translateVariables(...)"
1390 | - patterns:
1391 | - pattern-inside: |-
1392 | org.apache.struts2.util.StrutsUtil.makeSelectList($VAR, ...)
1393 | - pattern: "$VAR"
1394 | - patterns:
1395 | - pattern-inside: |-
1396 | (org.apache.struts2.views.jsp.ui.OgnlTool $T).findValue($VAR, ...)
1397 | - pattern: "$VAR"
1398 | - pattern: "(com.opensymphony.xwork2.util.ValueStack $V).findString(...)"
1399 | - patterns:
1400 | - pattern-inside: |-
1401 | (com.opensymphony.xwork2.util.ValueStack $V).findValue($VAR, ...)
1402 | - pattern: "$VAR"
1403 | - patterns:
1404 | - pattern-inside: |-
1405 | (com.opensymphony.xwork2.util.ValueStack $V).setValue($VAR, ...)
1406 | - pattern: "$VAR"
1407 | - patterns:
1408 | - pattern-inside: |-
1409 | (com.opensymphony.xwork2.util.ValueStack $V).setParameter($VAR, ...)
1410 | - pattern: "$VAR"
1411 | message: |
1412 | "A expression is built with a dynamic value. The source of the value(s) should be verified to
1413 | avoid that unfiltered values fall into this risky code evaluation."
1414 | languages:
1415 | - "java"
1416 | severity: "WARNING"
1417 | metadata:
1418 | category: "security"
1419 | technology:
1420 | - "java"
1421 | - id: "find_sec_bugs.PATH_TRAVERSAL_IN-1"
1422 | mode: "taint"
1423 | pattern-sources:
1424 | - patterns:
1425 | - pattern-inside: |
1426 | $FUNC(String[] $ARGS) {
1427 | ...
1428 | }
1429 | - pattern: "$ARGS[$IDX]"
1430 | - patterns:
1431 | - pattern-inside: |
1432 | $FUNC(..., String $VAR, ...) {
1433 | ...
1434 | }
1435 | - pattern: "$VAR"
1436 | pattern-sanitizers:
1437 | - pattern: "org.apache.commons.io.FilenameUtils.getName(...)"
1438 | pattern-sinks:
1439 | - patterns:
1440 | - pattern-inside: |
1441 | $U = new java.net.URI($VAR)
1442 | - pattern-either:
1443 | - pattern-inside: |-
1444 | new java.io.File($U)
1445 | - pattern-inside: |-
1446 | java.nio.file.Paths.get($U)
1447 | - pattern: "$VAR"
1448 | - patterns:
1449 | - pattern-inside: |-
1450 | new java.io.RandomAccessFile($INPUT,...)
1451 | - pattern: "$INPUT"
1452 | - pattern: "new java.io.FileReader(...)"
1453 | - pattern: "new javax.activation.FileDataSource(...)"
1454 | - pattern: "new java.io.FileInputStream(...)"
1455 | - patterns:
1456 | - pattern-either:
1457 | - pattern-inside: |-
1458 | new java.io.File(...,(String $VAR), ...)
1459 | - pattern-inside: |-
1460 | java.nio.file.Paths.get(...,(String $VAR),...)
1461 | - pattern-inside: |-
1462 | java.io.File.createTempFile(...,(String $VAR), ...)
1463 | - pattern-inside: |-
1464 | java.io.File.createTempDirectory(...,(String $VAR),...)
1465 | - pattern-inside: |-
1466 | java.nio.file.Files.createTempFile(..., (String $VAR), ...)
1467 | - pattern-inside: |-
1468 | java.nio.file.Files.createTempDirectory(..., (String $VAR), ...)
1469 | - pattern: "$VAR"
1470 | message: |
1471 | A file is opened to read its content. The filename comes from an input parameter. If an
1472 | unfiltered parameter is passed to this file API, files from an arbitrary filesystem location
1473 | could be read. This rule identifies potential path traversal vulnerabilities. In many cases,
1474 | the constructed file path cannot be controlled by the user.
1475 | languages:
1476 | - "java"
1477 | severity: "ERROR"
1478 | metadata:
1479 | category: "security"
1480 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
1481 | Traversal')"
1482 | technology:
1483 | - "java"
1484 | - id: "find_sec_bugs.PATH_TRAVERSAL_OUT-1.PATH_TRAVERSAL_OUT-1"
1485 | mode: "taint"
1486 | pattern-sources:
1487 | - patterns:
1488 | - pattern-inside: |
1489 | $FUNC(String[] $ARGS) {
1490 | ...
1491 | }
1492 | - pattern: "$ARGS[$IDX]"
1493 | - patterns:
1494 | - pattern-inside: |
1495 | $FUNC(..., String $VAR, ...) {
1496 | ...
1497 | }
1498 | - pattern: "$VAR"
1499 | pattern-sanitizers:
1500 | - pattern: "org.apache.commons.io.FilenameUtils.getName(...)"
1501 | pattern-sinks:
1502 | - patterns:
1503 | - pattern-inside: |-
1504 | new java.io.FileWriter($PATH, ...)
1505 | - pattern: "$PATH"
1506 | - patterns:
1507 | - pattern-inside: |-
1508 | new java.io.FileOutputStream($PATH, ...)
1509 | - pattern: "$PATH"
1510 | message: |
1511 | A file is opened to write to its contents. The filename comes from an input parameter. If an
1512 | unfiltered parameter is passed to this file API, files at an arbitrary filesystem location
1513 | could be modified. This rule identifies potential path traversal vulnerabilities. In many
1514 | cases, the constructed file path cannot be controlled by the user.
1515 | languages:
1516 | - "java"
1517 | severity: "ERROR"
1518 | metadata:
1519 | category: "security"
1520 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
1521 | Traversal')"
1522 | technology:
1523 | - "java"
1524 | - id: "find_sec_bugs.PT_ABSOLUTE_PATH_TRAVERSAL-1"
1525 | mode: "taint"
1526 | pattern-sources:
1527 | - pattern: "(HttpServletRequest $REQ).getParameter(...)"
1528 | pattern-sanitizers:
1529 | - pattern: "org.apache.commons.io.FilenameUtils.getName(...)"
1530 | pattern-sinks:
1531 | - patterns:
1532 | - pattern-inside: |
1533 | $U = new java.net.URI($VAR)
1534 | - pattern-either:
1535 | - pattern-inside: |-
1536 | new java.io.File($U)
1537 | - pattern-inside: |-
1538 | java.nio.file.Paths.get($U)
1539 | - pattern: "$VAR"
1540 | - patterns:
1541 | - pattern-inside: |-
1542 | new java.io.RandomAccessFile($INPUT,...)
1543 | - pattern: "$INPUT"
1544 | - pattern: "new java.io.FileReader(...)"
1545 | - pattern: "new javax.activation.FileDataSource(...)"
1546 | - pattern: "new java.io.FileInputStream(...)"
1547 | - pattern: "new java.io.File(...)"
1548 | - pattern: "java.nio.file.Paths.get(...)"
1549 | - pattern: "java.io.File.createTempFile(...)"
1550 | - pattern: "java.io.File.createTempDirectory(...)"
1551 | - pattern: "java.nio.file.Files.createTempFile(...)"
1552 | - pattern: "java.nio.file.Files.createTempDirectory(...)"
1553 | - patterns:
1554 | - pattern-inside: |-
1555 | new java.io.FileWriter($PATH, ...)
1556 | - pattern: "$PATH"
1557 | - patterns:
1558 | - pattern-inside: |-
1559 | new java.io.FileOutputStream($PATH, ...)
1560 | - pattern: "$PATH"
1561 | message: |
1562 | "The software uses an HTTP request parameter to construct a pathname that should be within a
1563 | restricted directory, but it does not properly neutralize absolute path sequences such as
1564 | "/abs/path" that can resolve to a location that is outside of that directory. See
1565 | http://cwe.mitre.org/data/definitions/36.html for more information."
1566 | languages:
1567 | - "java"
1568 | severity: "WARNING"
1569 | metadata:
1570 | category: "security"
1571 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
1572 | Traversal')"
1573 | technology:
1574 | - "java"
1575 | - id: "find_sec_bugs.PT_RELATIVE_PATH_TRAVERSAL-1"
1576 | mode: "taint"
1577 | pattern-sources:
1578 | - patterns:
1579 | - pattern-inside: |
1580 | $P = (HttpServletRequest $REQ).getParameter(...);
1581 | ...
1582 | - pattern-either:
1583 | - pattern: "$P + ..."
1584 | - pattern: "... + $P"
1585 | pattern-sanitizers:
1586 | - pattern: "org.apache.commons.io.FilenameUtils.getName(...)"
1587 | pattern-sinks:
1588 | - patterns:
1589 | - pattern-inside: |
1590 | $U = new java.net.URI($VAR)
1591 | - pattern-either:
1592 | - pattern-inside: |-
1593 | new java.io.File($U)
1594 | - pattern-inside: |-
1595 | java.nio.file.Paths.get($U)
1596 | - pattern: "$VAR"
1597 | - patterns:
1598 | - pattern-inside: |-
1599 | new java.io.RandomAccessFile($INPUT,...)
1600 | - pattern: "$INPUT"
1601 | - pattern: "new java.io.FileReader(...)"
1602 | - pattern: "new javax.activation.FileDataSource(...)"
1603 | - pattern: "new java.io.FileInputStream(...)"
1604 | - pattern: "new java.io.File(...)"
1605 | - pattern: "java.nio.file.Paths.get(...)"
1606 | - pattern: "java.io.File.createTempFile(...)"
1607 | - pattern: "java.io.File.createTempDirectory(...)"
1608 | - pattern: "java.nio.file.Files.createTempFile(...)"
1609 | - pattern: "java.nio.file.Files.createTempDirectory(...)"
1610 | - patterns:
1611 | - pattern-inside: |-
1612 | new java.io.FileWriter($PATH, ...)
1613 | - pattern: "$PATH"
1614 | - patterns:
1615 | - pattern-inside: |-
1616 | new java.io.FileOutputStream($PATH, ...)
1617 | - pattern: "$PATH"
1618 | message: |
1619 | "The software uses an HTTP request parameter to construct a pathname that should be within a
1620 | restricted directory, but it does not properly neutralize sequences such as ".." that can
1621 | resolve to a location that is outside of that directory. See
1622 | http://cwe.mitre.org/data/definitions/23.html for more information."
1623 | languages:
1624 | - "java"
1625 | severity: "WARNING"
1626 | metadata:
1627 | category: "security"
1628 | cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
1629 | Traversal')"
1630 | technology:
1631 | - "java"
1632 | - id: "find_sec_bugs.SQL_INJECTION_SPRING_JDBC-1.SQL_INJECTION_JPA-1.SQL_INJECTION_JDO-1.SQL_INJECTION_JDBC-1.SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE-1"
1633 | pattern-either:
1634 | - patterns:
1635 | - pattern: "(javax.jdo.PersistenceManager $PM).newQuery($ARG)"
1636 | - pattern-not: "(javax.jdo.PersistenceManager $PM).newQuery(\"...\")"
1637 | - patterns:
1638 | - pattern: "(javax.jdo.PersistenceManager $PM).newQuery(..., $ARG)"
1639 | - pattern-not: "(javax.jdo.PersistenceManager $PM).newQuery(..., \"...\")"
1640 | - patterns:
1641 | - pattern: "(javax.jdo.Query $Q).setFilter($ARG)"
1642 | - pattern-not: "(javax.jdo.Query $Q).setFilter(\"...\")"
1643 | - patterns:
1644 | - pattern: "(javax.jdo.Query $Q).setGrouping($ARG)"
1645 | - pattern-not: "(javax.jdo.Query $Q).setGrouping(\"...\")"
1646 | - patterns:
1647 | - pattern: "(javax.jdo.Query $Q).setGrouping($ARG)"
1648 | - pattern-not: "(javax.jdo.Query $Q).setGrouping(\"...\")"
1649 | - patterns:
1650 | - pattern: "(org.hibernate.criterion.Restrictions $H).sqlRestriction($ARG, ...)"
1651 | - pattern-not: "(org.hibernate.criterion.Restrictions $H).sqlRestriction(\"...\",
1652 | ...)"
1653 | - patterns:
1654 | - pattern: "(org.hibernate.Session $S).createQuery($ARG, ...)"
1655 | - pattern-not: "(org.hibernate.Session $S).createQuery(\"...\", ...)"
1656 | - patterns:
1657 | - pattern: "(org.hibernate.Session $S).createSQLQuery($ARG, ...)"
1658 | - pattern-not: "(org.hibernate.Session $S).createSQLQuery(\"...\", ...)"
1659 | - patterns:
1660 | - pattern: "(java.sql.Statement $S).executeQuery($ARG, ...)"
1661 | - pattern-not: "(java.sql.Statement $S).createSQLQuery(\"...\", ...)"
1662 | - patterns:
1663 | - pattern: "(java.sql.Statement $S).execute($ARG, ...)"
1664 | - pattern-not: "(java.sql.Statement $S).execute(\"...\", ...)"
1665 | - patterns:
1666 | - pattern: "(java.sql.Statement $S).executeUpdate($ARG, ...)"
1667 | - pattern-not: "(java.sql.Statement $S).executeUpdate(\"...\", ...)"
1668 | - patterns:
1669 | - pattern: "(java.sql.Statement $S).executeLargeUpdate($ARG, ...)"
1670 | - pattern-not: "(java.sql.Statement $S).executeLargeUpdate(\"...\", ...)"
1671 | - patterns:
1672 | - pattern: "(java.sql.Statement $S).addBatch($ARG, ...)"
1673 | - pattern-not: "(java.sql.Statement $S).addBatch(\"...\", ...)"
1674 | - patterns:
1675 | - pattern: "(java.sql.PreparedStatement $S).executeQuery($ARG, ...)"
1676 | - pattern-not: "(java.sql.PreparedStatement $S).executeQuery(\"...\", ...)"
1677 | - patterns:
1678 | - pattern: "(java.sql.PreparedStatement $S).execute($ARG, ...)"
1679 | - pattern-not: "(java.sql.PreparedStatement $S).execute(\"...\", ...)"
1680 | - patterns:
1681 | - pattern: "(java.sql.PreparedStatement $S).executeUpdate($ARG, ...)"
1682 | - pattern-not: "(java.sql.PreparedStatement $S).executeUpdate(\"...\", ...)"
1683 | - patterns:
1684 | - pattern: "(java.sql.PreparedStatement $S).executeLargeUpdate($ARG, ...)"
1685 | - pattern-not: "(java.sql.PreparedStatement $S).executeLargeUpdate(\"...\", ...)"
1686 | - patterns:
1687 | - pattern: "(java.sql.PreparedStatement $S).addBatch($ARG, ...)"
1688 | - pattern-not: "(java.sql.PreparedStatement $S).addBatch(\"...\", ...)"
1689 | - patterns:
1690 | - pattern: "(java.sql.Connection $S).prepareCall($ARG, ...)"
1691 | - pattern-not: "(java.sql.Connection $S).prepareCall(\"...\", ...)"
1692 | - patterns:
1693 | - pattern: "(java.sql.Connection $S).prepareStatement($ARG, ...)"
1694 | - pattern-not: "(java.sql.Connection $S).prepareStatement(\"...\", ...)"
1695 | - patterns:
1696 | - pattern: "(java.sql.Connection $S).nativeSQL($ARG, ...)"
1697 | - pattern-not: "(java.sql.Connection $S).nativeSQL(\"...\", ...)"
1698 | - patterns:
1699 | - pattern: "new org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG,
1700 | ...)"
1701 | - pattern-not: "new org.springframework.jdbc.core.PreparedStatementCreatorFactory(\"...\",
1702 | ...)"
1703 | - patterns:
1704 | - pattern: "(org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator($ARG,
1705 | ...)"
1706 | - pattern-not: "(org.springframework.jdbc.core.PreparedStatementCreatorFactory
1707 | $F).newPreparedStatementCreator(\"...\", ...)"
1708 | - patterns:
1709 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).batchUpdate($ARG,
1710 | ...)"
1711 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).batchUpdate(\"...\",
1712 | ...)"
1713 | - patterns:
1714 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).execute($ARG, ...)"
1715 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).execute(\"...\",
1716 | ...)"
1717 | - patterns:
1718 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).query($ARG, ...)"
1719 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).query(\"...\",
1720 | ...)"
1721 | - patterns:
1722 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForList($ARG,
1723 | ...)"
1724 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForList(\"...\",
1725 | ...)"
1726 | - patterns:
1727 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForMap($ARG,
1728 | ...)"
1729 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForMap(\"...\",
1730 | ...)"
1731 | - patterns:
1732 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG,
1733 | ...)"
1734 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForObject(\"...\",
1735 | ...)"
1736 | - patterns:
1737 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG,
1738 | ...)"
1739 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForObject(\"...\",
1740 | ...)"
1741 | - patterns:
1742 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForRowSet($ARG,
1743 | ...)"
1744 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForRowSet(\"...\",
1745 | ...)"
1746 | - patterns:
1747 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForInt($ARG,
1748 | ...)"
1749 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForInt(\"...\",
1750 | ...)"
1751 | - patterns:
1752 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).queryForLong($ARG,
1753 | ...)"
1754 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).queryForLong(\"...\",
1755 | ...)"
1756 | - patterns:
1757 | - pattern: "(org.springframework.jdbc.core.JdbcOperations $O).udpate($ARG, ...)"
1758 | - pattern-not: "(org.springframework.jdbc.core.JdbcOperations $O).udpate(\"...\",
1759 | ...)"
1760 | - patterns:
1761 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).batchUpdate($ARG,
1762 | ...)"
1763 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).batchUpdate(\"...\",
1764 | ...)"
1765 | - patterns:
1766 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).execute($ARG, ...)"
1767 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).execute(\"...\",
1768 | ...)"
1769 | - patterns:
1770 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).query($ARG, ...)"
1771 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).query(\"...\",
1772 | ...)"
1773 | - patterns:
1774 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForList($ARG,
1775 | ...)"
1776 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForList(\"...\",
1777 | ...)"
1778 | - patterns:
1779 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForMap($ARG,
1780 | ...)"
1781 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForMap(\"...\",
1782 | ...)"
1783 | - patterns:
1784 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForObject($ARG,
1785 | ...)"
1786 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForObject(\"...\",
1787 | ...)"
1788 | - patterns:
1789 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForRowSet($ARG,
1790 | ...)"
1791 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForRowSet(\"...\",
1792 | ...)"
1793 | - patterns:
1794 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForInt($ARG,
1795 | ...)"
1796 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForInt(\"...\",
1797 | ...)"
1798 | - patterns:
1799 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForLong($ARG,
1800 | ...)"
1801 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).queryForLong(\"...\",
1802 | ...)"
1803 | - patterns:
1804 | - pattern: "(org.springframework.jdbc.core.JdbcTemplate $O).update($ARG, ...)"
1805 | - pattern-not: "(org.springframework.jdbc.core.JdbcTemplate $O).update(\"...\",
1806 | ...)"
1807 | - patterns:
1808 | - pattern: "(io.vertx.sqlclient.SqlClient $O).query($ARG, ...)"
1809 | - pattern-not: "(io.vertx.sqlclient.SqlClient $O).query(\"...\", ...)"
1810 | - patterns:
1811 | - pattern: "(io.vertx.sqlclient.SqlClient $O).preparedQuery($ARG, ...)"
1812 | - pattern-not: "(io.vertx.sqlclient.SqlClient $O).preparedQuery(\"...\", ...)"
1813 | - patterns:
1814 | - pattern: "(io.vertx.sqlclient.SqlConnection $O).prepare($ARG, ...)"
1815 | - pattern-not: "(io.vertx.sqlclient.SqlConnection $O).prepare(\"...\", ...)"
1816 | - patterns:
1817 | - pattern: "(org.apache.turbine.om.peer.BasePeer $O).executeQuery($ARG, ...)"
1818 | - pattern-not: "(org.apache.turbine.om.peer.BasePeer $O).executeQuery(\"...\",
1819 | ...)"
1820 | - patterns:
1821 | - pattern: "(org.apache.torque.util.BasePeer $O).executeQuery($ARG, ...)"
1822 | - pattern-not: "(org.apache.torque.util.BasePeer $O).executeQuery(\"...\", ...)"
1823 | - patterns:
1824 | - pattern: "(javax.persistence.EntityManager $O).createQuery($ARG, ...)"
1825 | - pattern-not: "(javax.persistence.EntityManager $O).createQuery(\"...\", ...)"
1826 | - patterns:
1827 | - pattern: "(javax.persistence.EntityManager $O).createNativeQuery($ARG, ...)"
1828 | - pattern-not: "(javax.persistence.EntityManager $O).createNativeQuery(\"...\",
1829 | ...)"
1830 | languages:
1831 | - "java"
1832 | message: |
1833 | The input values included in SQL queries need to be passed in safely. Bind
1834 | variables in prepared statements can be used to easily mitigate the risk of
1835 | SQL injection.
1836 | metadata:
1837 | category: "security"
1838 | cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command
1839 | ('SQL Injection')"
1840 | severity: "ERROR"
1841 | - id: "find_sec_bugs.LDAP_ANONYMOUS-1"
1842 | patterns:
1843 | - pattern-inside: |
1844 | import javax.naming.Context;
1845 | ...
1846 | - pattern: "$ENV.put(Context.SECURITY_AUTHENTICATION, \"none\");"
1847 | languages:
1848 | - "java"
1849 | message: |
1850 | Without proper access control, executing an LDAP statement that contains a
1851 | user-controlled value can allow an attacker to abuse poorly configured LDAP
1852 | context
1853 | metadata:
1854 | category: "security"
1855 | cwe: "CWE-20: Improper Input Validation"
1856 | severity: "WARNING"
1857 | - id: "find_sec_bugs.LDAP_ENTRY_POISONING-1"
1858 | patterns:
1859 | - pattern: "new javax.naming.directory.SearchControls($SCOPE, $CLIMIT, $TLIMIT,
1860 | $ATTR, true, $DEREF)"
1861 | languages:
1862 | - "java"
1863 | message: |
1864 | Without proper access control, executing an LDAP statement that contains a
1865 | user-controlled value can allow an attacker to abuse poorly configured LDAP
1866 | context
1867 | metadata:
1868 | category: "security"
1869 | cwe: "CWE-20: Improper Input Validation"
1870 | severity: "ERROR"
1871 | - id: "find_sec_bugs.DMI_CONSTANT_DB_PASSWORD-1.HARD_CODE_PASSWORD-3"
1872 | patterns:
1873 | - pattern: "java.sql.DriverManager.getConnection($URI, $USR, \"...\");"
1874 | message: |
1875 | This code creates a database connect using a hardcoded, constant password. Anyone with access
1876 | to either the source code or the compiled code can easily learn the password.
1877 | languages:
1878 | - "java"
1879 | severity: "WARNING"
1880 | metadata:
1881 | category: "security"
1882 | cwe: "CWE-259: Use of Hard-coded Password"
1883 | technology:
1884 | - "java"
1885 | - id: "find_sec_bugs.DMI_EMPTY_DB_PASSWORD-1.HARD_CODE_PASSWORD-2"
1886 | patterns:
1887 | - pattern: "java.sql.DriverManager.getConnection($URI, $USR, \"\");"
1888 | message: |
1889 | This code creates a database connect using a blank or empty password. This indicates that the
1890 | database is not protected by a password.
1891 | languages:
1892 | - "java"
1893 | severity: "WARNING"
1894 | metadata:
1895 | category: "security"
1896 | cwe: "CWE-259: Use of Hard-coded Password"
1897 | technology:
1898 | - "java"
1899 | - id: "find_sec_bugs.HARD_CODE_KEY-1"
1900 | pattern-either:
1901 | - patterns:
1902 | - pattern-not-inside: |
1903 | $FUNC(...,byte[] $KEY_BYTES, ...) {
1904 | ...
1905 | }
1906 | - pattern-either:
1907 | - pattern: "new DESKeySpec((byte[] $KEY_BYTES));"
1908 | - pattern: "new DESedeKeySpec((byte[] $KEY_BYTES));"
1909 | - pattern: "new KerberosKey(..., (byte[] $KEY_BYTES), ..., ...);"
1910 | - pattern: "new SecretKeySpec((byte[] $KEY_BYTES), ...);"
1911 | - pattern: "new X509EncodedKeySpec((byte[] $KEY_BYTES));"
1912 | - pattern: "new PKCS8EncodedKeySpec((byte[] $KEY_BYTES));"
1913 | - pattern: "new KeyRep(...,(byte[] $KEY_BYTES));"
1914 | - pattern: "new KerberosTicket(...,(byte[] $KEY_BYTES),...);"
1915 | - metavariable-pattern:
1916 | metavariable: "$KEY_BYTES"
1917 | patterns:
1918 | - pattern-not-regex: "(null)"
1919 | - patterns:
1920 | - pattern-not-inside: |
1921 | $FUNC(..., BigInteger $PRIVATE_KEY, ...) {
1922 | ...
1923 | }
1924 | - pattern-either:
1925 | - pattern: "new DSAPrivateKeySpec((BigInteger $PRIVATE_KEY), ...);"
1926 | - pattern: "new DSAPublicKeySpec((BigInteger $PRIVATE_KEY), ...);"
1927 | - pattern: "new DHPrivateKeySpec((BigInteger $PRIVATE_KEY), ...);"
1928 | - pattern: "new DHPublicKeySpec((BigInteger $PRIVATE_KEY), ...);"
1929 | - pattern: "new ECPrivateKeySpec((BigInteger $PRIVATE_KEY), ...);"
1930 | - pattern: "new RSAPrivateKeySpec((BigInteger $PRIVATE_KEY), ...);"
1931 | - pattern: "new RSAMultiPrimePrivateCrtKeySpec((BigInteger $PRIVATE_KEY), ...);"
1932 | - pattern: "new RSAPrivateCrtKeySpec((BigInteger $PRIVATE_KEY), ...);"
1933 | - pattern: "new RSAPublicKeySpec((BigInteger $PRIVATE_KEY), ...);"
1934 | - metavariable-pattern:
1935 | metavariable: "$PRIVATE_KEY"
1936 | patterns:
1937 | - pattern-not-regex: "(null)"
1938 | message: |
1939 | Cryptographic keys should not be kept in the source code. The source code can be widely shared
1940 | in an enterprise environment, and is certainly shared in open source. To be managed safely,
1941 | passwords and secret keys should be stored in separate configuration files or keystores.
1942 | languages:
1943 | - "java"
1944 | severity: "ERROR"
1945 | metadata:
1946 | category: "security"
1947 | cwe: "CWE-321: Use of Hard-coded Cryptographic Key"
1948 | technology:
1949 | - "java"
1950 | - id: "find_sec_bugs.HARD_CODE_KEY-4"
1951 | patterns:
1952 | - pattern-not-inside: |
1953 | $FUNC(..., $VAR_NAME, ...) {
1954 | ...
1955 | }
1956 | - pattern-either:
1957 | - pattern: "(String $VAR_NAME).equals(...)"
1958 | - pattern: "(String $OTHER).equals((String $VAR_NAME))"
1959 | - pattern: "java.util.Arrays.equals(...,(String $VAR_NAME),...)"
1960 | - pattern: "(byte[] $VAR_NAME).equals(...)"
1961 | - pattern: "(byte[] $OTHER).equals((byte[] $VAR_NAME))"
1962 | - pattern: "java.util.Arrays.equals(...,(byte[] $VAR_NAME),...)"
1963 | - pattern: "java.lang.Byte.comapre(...,(byte[] $VAR_NAME),...)"
1964 | - pattern: "(char[] $VAR_NAME).equals(...)"
1965 | - pattern: "(char[] $OTHER).equals((char[] $VAR_NAME))"
1966 | - pattern: "java.util.Arrays.equals(...,(char[] $VAR_NAME),...)"
1967 | - metavariable-regex:
1968 | metavariable: "$VAR_NAME"
1969 | regex: "(?i).*(pass|pwd|psw|secret|key|cipher|crypt|des|aes|mac|private|sign|cert).*"
1970 | message: |
1971 | Cryptographic keys should not be kept in the source code. The source code can be widely shared
1972 | in an enterprise environment, and is certainly shared in open source. To be managed safely,
1973 | passwords and secret keys should be stored in separate configuration files or keystores.
1974 | languages:
1975 | - "java"
1976 | severity: "WARNING"
1977 | metadata:
1978 | category: "security"
1979 | cwe: "CWE-321: Use of Hard-coded Cryptographic Key"
1980 | technology:
1981 | - "java"
1982 | - id: "find_sec_bugs.HARD_CODE_KEY-2"
1983 | patterns:
1984 | - pattern-either:
1985 | - pattern: "String $VAR = \"...\";"
1986 | - pattern: "byte[] $VAR = {...};"
1987 | - pattern: "byte[] $VAR = new byte[]{...};"
1988 | - pattern: "char[] $VAR = {...};"
1989 | - pattern: "char[] $VAR = new char[]{...};"
1990 | - metavariable-regex:
1991 | metavariable: "$VAR"
1992 | regex: "(?i).*(pass|pwd|psw|secret|key|cipher|crypt|des|aes|mac|private|sign|cert).*"
1993 | message: |
1994 | Cryptographic keys should not be kept in the source code. The source code can be widely shared
1995 | in an enterprise environment, and is certainly shared in open source. To be managed safely,
1996 | passwords and secret keys should be stored in separate configuration files or keystores.
1997 | languages:
1998 | - "java"
1999 | severity: "WARNING"
2000 | metadata:
2001 | category: "security"
2002 | cwe: "CWE-321: Use of Hard-coded Cryptographic Key"
2003 | technology:
2004 | - "java"
2005 | - id: "find_sec_bugs.HARD_CODE_KEY-3"
2006 | patterns:
2007 | - pattern: "String $VAR = \"$VAL\";"
2008 | - metavariable-regex:
2009 | metavariable: "$VAL"
2010 | regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).*"
2011 | message: |
2012 | Cryptographic keys should not be kept in the source code. The source code can be widely shared
2013 | in an enterprise environment, and is certainly shared in open source. To be managed safely,
2014 | passwords and secret keys should be stored in separate configuration files or keystores.
2015 | languages:
2016 | - "java"
2017 | severity: "WARNING"
2018 | metadata:
2019 | category: "security"
2020 | cwe: "CWE-321: Use of Hard-coded Cryptographic Key"
2021 | technology:
2022 | - "java"
2023 | - id: "find_sec_bugs.HARD_CODE_PASSWORD-1"
2024 | patterns:
2025 | - pattern-either:
2026 | - pattern-inside: |
2027 | char[] $PWD = ...;
2028 | ...
2029 | - pattern: "(KeyStore $KS).load(..., $PWD)"
2030 | - pattern: "new PBEKeySpec($PWD, ...)"
2031 | - pattern: "new PasswordAuthentication(\"...\", $PWD)"
2032 | - pattern: "(PasswordCallback $CB).setPassword($PWD)"
2033 | - pattern: "new KeyStore.PasswordProtection($PWD)"
2034 | - pattern: "new KerberosKey(...,$PWD,...);"
2035 | - pattern: "(javax.net.ssl.KeyManagerFactory $KMF).init(..., $PWD);"
2036 | - metavariable-pattern:
2037 | metavariable: "$PWD"
2038 | patterns:
2039 | - pattern-not-regex: "(null)"
2040 | message: |
2041 | Passwords should not be kept in the source code. The source code can be widely shared in an
2042 | enterprise environment, and is certainly shared in open source. To be managed safely, passwords
2043 | and secret keys should be stored in separate configuration files or keystores.
2044 | languages:
2045 | - "java"
2046 | severity: "ERROR"
2047 | metadata:
2048 | category: "security"
2049 | cwe: "CWE-259: Use of Hard-coded Password"
2050 | technology:
2051 | - "java"
2052 | - id: "find_sec_bugs.DANGEROUS_PERMISSION_COMBINATION-1"
2053 | pattern-either:
2054 | - pattern: |
2055 | $RUNVAR = new RuntimePermission("createClassLoader");
2056 | ...
2057 | (PermissionCollection $PC).add($RUNVAR);
2058 | - pattern: |
2059 | $REFVAR = new ReflectPermission("suppressAccessChecks");
2060 | ...
2061 | (PermissionCollection $PC).add($REFVAR);
2062 | - pattern: "(PermissionCollection $PC).add(new ReflectPermission(\"suppressAccessChecks\"))"
2063 | - pattern: "(PermissionCollection $PC).add(new RuntimePermission(\"createClassLoader\"))"
2064 | languages:
2065 | - "java"
2066 | message: |
2067 | Do not grant dangerous combinations of permissions.
2068 | metadata:
2069 | category: "security"
2070 | confidence: "HIGH"
2071 | severity: "WARNING"
2072 | - id: "find_sec_bugs.OVERLY_PERMISSIVE_FILE_PERMISSION-1"
2073 | patterns:
2074 | - pattern-either:
2075 | - pattern: "java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString(\"$PERM_STRING\"));"
2076 | - pattern: |
2077 | $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING");
2078 | ...
2079 | java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS);
2080 | - metavariable-regex:
2081 | metavariable: "$PERM_STRING"
2082 | regex: "[rwx-]{6}[rwx]{1,}"
2083 | languages:
2084 | - "java"
2085 | message: |
2086 | Overly permissive file permission
2087 | metadata:
2088 | cwe: "CWE-732: Incorrect Permission Assignment for Critical Resource"
2089 | category: "security"
2090 | confidence: "HIGH"
2091 | severity: "WARNING"
2092 | - id: "find_sec_bugs.OVERLY_PERMISSIVE_FILE_PERMISSION-2"
2093 | patterns:
2094 | - pattern-inside: |
2095 | $PERMS.add($P);
2096 | ...
2097 | java.nio.file.Files.setPosixFilePermissions(..., $PERMS);
2098 | - metavariable-regex:
2099 | metavariable: "$P"
2100 | regex: "(PosixFilePermission.){0,1}(OTHERS_)"
2101 | languages:
2102 | - "java"
2103 | message: |
2104 | Overly permissive file permission
2105 | metadata:
2106 | cwe: "CWE-732: Incorrect Permission Assignment for Critical Resource"
2107 | category: "security"
2108 | confidence: "HIGH"
2109 | severity: "WARNING"
2110 | - id: "find_sec_bugs.PREDICTABLE_RANDOM-1"
2111 | patterns:
2112 | - pattern-either:
2113 | - pattern: |
2114 | java.util.Random $R = new java.util.Random();
2115 | ...
2116 | $R.$METHOD();
2117 | - pattern: "(java.util.Random $R).$METHOD()"
2118 | - pattern: "new java.util.Random().$METHOD()"
2119 | - pattern: "org.apache.commons.lang.math.RandomUtils.$METHOD()"
2120 | - pattern: "org.apache.commons.lang.RandomStringUtils.$METHOD(...)"
2121 | - metavariable-regex:
2122 | metavariable: "$METHOD"
2123 | regex: "^(next|random)"
2124 | message: |
2125 | The use of a predictable random value can lead to vulnerabilities when
2126 | used in certain security critical contexts. A quick fix could be to replace
2127 | the use of java.util.Random with something stronger, such as java.security.SecureRandom.
2128 | languages:
2129 | - "java"
2130 | severity: "WARNING"
2131 | metadata:
2132 | category: "security"
2133 | cwe: "CWE-330: Use of Insufficiently Random Values"
2134 | technology:
2135 | - "java"
2136 | - id: "find_sec_bugs.SCRIPT_ENGINE_INJECTION-1.SPEL_INJECTION-1.EL_INJECTION-2.SEAM_LOG_INJECTION-1"
2137 | patterns:
2138 | - pattern: "(javax.script.ScriptEngine $ENGINE).eval($ARG);"
2139 | - pattern-not: "(javax.script.ScriptEngine $ENGINE).eval(\"...\");"
2140 | message: |
2141 | The software constructs all or part of a code segment using externally-influenced
2142 | input from an upstream component, but it does not neutralize or incorrectly
2143 | neutralizes special elements that could modify the syntax or behavior of the
2144 | intended code segment.
2145 | languages:
2146 | - "java"
2147 | severity: "ERROR"
2148 | metadata:
2149 | cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
2150 | - id: "find_sec_bugs.SCRIPT_ENGINE_INJECTION-2"
2151 | patterns:
2152 | - pattern: "(org.springframework.expression.spel.standard.SpelExpressionParser $P).parseExpression($ARG);"
2153 | - pattern-not: "(org.springframework.expression.spel.standard.SpelExpressionParser
2154 | $P).parseExpression(\"...\");"
2155 | message: |
2156 | The software constructs all or part of a code segment using externally-influenced
2157 | input from an upstream component, but it does not neutralize or incorrectly
2158 | neutralizes special elements that could modify the syntax or behavior of the
2159 | intended code segment.
2160 | languages:
2161 | - "java"
2162 | severity: "ERROR"
2163 | metadata:
2164 | cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
2165 | - id: "find_sec_bugs.INSECURE_SMTP_SSL-1"
2166 | patterns:
2167 | - pattern-either:
2168 | - pattern-inside: |
2169 | $E = new org.apache.commons.mail.SimpleEmail(...);
2170 | ...
2171 | - pattern-inside: |
2172 | $E = new org.apache.commons.mail.Email(...);
2173 | ...
2174 | - pattern-inside: |
2175 | $E = new org.apache.commons.mail.MultiPartEmail(...);
2176 | ...
2177 | - pattern-inside: |
2178 | $E = new org.apache.commons.mail.HtmlEmail(...);
2179 | ...
2180 | - pattern-inside: |
2181 | $E = new org.apache.commons.mail.ImageHtmlEmail(...);
2182 | ...
2183 | - pattern-not: "$E.setSSLOnConnect(true);\n...\n$E.setSSLCheckServerIdentity(true);\n"
2184 | message: |
2185 | Server identity verification is disabled when making SSL connections.
2186 | metadata:
2187 | cwe: "CWE-297: Improper Validation of Certificate with Host Mismatch"
2188 | severity: "ERROR"
2189 | languages:
2190 | - "java"
2191 | - id: "find_sec_bugs.SMTP_HEADER_INJECTION-1"
2192 | patterns:
2193 | - pattern-either:
2194 | - patterns:
2195 | - pattern-inside: |
2196 | $M = new MimeMessage(...);
2197 | ...
2198 | - pattern: "$M.setSubject($ARG);"
2199 | - pattern-not: "$M.setSubject(\"...\")"
2200 | - patterns:
2201 | - pattern-inside: |
2202 | $M = new MimeMessage(...);
2203 | ...
2204 | - pattern: "$M.addHeader($ARG1, $ARG2)"
2205 | - pattern-not: "$M.addHeader(\"...\", \"...\")"
2206 | - patterns:
2207 | - pattern-inside: |
2208 | $M = new MimeMessage(...);
2209 | ...
2210 | - pattern: "$M.setDescription($ARG)"
2211 | - pattern-not: "$M.setDescription(\"...\")"
2212 | - patterns:
2213 | - pattern-inside: |
2214 | $M = new MimeMessage(...);
2215 | ...
2216 | - pattern: "$M.setDisposition($ARG)"
2217 | - pattern-not: "$M.setDisposition(\"...\")"
2218 | languages:
2219 | - "java"
2220 | message: |
2221 | Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for
2222 | email delivery. Like with HTTP, headers are separate by new line separator. If
2223 | kuser input is place in a header line, the application should remove or replace
2224 | new line characters (CR / LF). You should use a safe wrapper such as Apache
2225 | Common Email and Simple Java Mail which filter special characters that can lead
2226 | to header injection.
2227 | metadata:
2228 | category: "security"
2229 | cwe: "CWE-77: Improper Neutralization of Special Elements used in a Command"
2230 | severity: "ERROR"
2231 | - id: "find_sec_bugs.URLCONNECTION_SSRF_FD-1"
2232 | pattern-either:
2233 | - patterns:
2234 | - pattern: "new URL(...). ... .connect()"
2235 | - pattern-not: "new URL(\"...\"). ... .connect()"
2236 | - patterns:
2237 | - pattern: "new URL(...). ... .GetContent(...)"
2238 | - pattern-not: "new URL(\"...\"). ... .GetContent(...)"
2239 | - patterns:
2240 | - pattern: "new URL(...). ... .openConnection(...)"
2241 | - pattern-not: "new URL(\"...\"). ... .openConnection(...)"
2242 | - patterns:
2243 | - pattern: "new URL(...). ... .openStream(...)"
2244 | - pattern-not: "new URL(\"...\"). ... .openStream(...)"
2245 | - patterns:
2246 | - pattern: "new URL(...). ... .getContent(...)"
2247 | - pattern-not: "new URL(\"...\"). ... .getContent(...)"
2248 | languages:
2249 | - "java"
2250 | message: |
2251 | Server-Side Request Forgery occur when a web server executes a request to a
2252 | user supplied destination parameter that is not validated. Such vulnerabilities
2253 | could allow an attacker to access internal services or to launch attacks from
2254 | your web server.
2255 | metadata:
2256 | category: "security"
2257 | cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
2258 | severity: "ERROR"
2259 | - id: "find_sec_bugs.BAD_HEXA_CONVERSION-1"
2260 | patterns:
2261 | - pattern: |
2262 | $B_ARR = (java.security.MessageDigest $MD).digest(...);
2263 | ...
2264 | for(...) {
2265 | ...
2266 | Integer.toHexString(...);
2267 | }
2268 | languages:
2269 | - "java"
2270 | message: |
2271 | When converting a byte array containing a hash signature to a human readable string, a
2272 | conversion mistake can be made if the array is read byte by byte.
2273 | metadata:
2274 | cwe: "CWE-704: Incorrect Type Conversion or Cast"
2275 | category: "security"
2276 | confidence: "HIGH"
2277 | severity: "WARNING"
2278 | - id: "find_sec_bugs.FORMAT_STRING_MANIPULATION-1"
2279 | patterns:
2280 | - pattern-either:
2281 | - patterns:
2282 | - pattern-inside: |
2283 | String $INPUT = (HttpServletRequest $REQ).getParameter(...);
2284 | ...
2285 | - pattern-inside: |
2286 | String $FORMAT_STR = ... + $INPUT;
2287 | ...
2288 | - patterns:
2289 | - pattern-inside: |
2290 | String $INPUT = (HttpServletRequest $REQ).getParameter(...);
2291 | ...
2292 | - pattern-inside: |
2293 | String $FORMAT_STR = ... + $INPUT + ...;
2294 | ...
2295 | - pattern-inside: |
2296 | String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...) + ...;
2297 | ...
2298 | - pattern-inside: |
2299 | String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...);
2300 | ...
2301 | - pattern-either:
2302 | - pattern: "String.format($FORMAT_STR, ...);"
2303 | - pattern: "String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...);"
2304 | - pattern: "(java.util.Formatter $F).format($FORMAT_STR, ...);"
2305 | - pattern: "(java.util.Formatter $F).format(java.util.Locale.$LOCALE, $FORMAT_STR,
2306 | ...);"
2307 | - pattern: "(java.io.PrintStream $F).printf($FORMAT_STR, ...);"
2308 | - pattern: "(java.io.PrintStream $F).printf(java.util.Locale.$LOCALE, $FORMAT_STR,
2309 | ...);"
2310 | - pattern: "(java.io.PrintStream $F).format($FORMAT_STR, ...);"
2311 | - pattern: "(java.io.PrintStream $F).format(java.util.Locale.$LOCALE, $FORMAT_STR,
2312 | ...);"
2313 | - pattern: "System.out.printf($FORMAT_STR, ...);"
2314 | - pattern: "System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...);"
2315 | - pattern: "System.out.format($FORMAT_STR, ...);"
2316 | - pattern: "System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...);"
2317 | languages:
2318 | - "java"
2319 | message: |
2320 | Allowing user input to control format parameters could enable an attacker to cause exceptions
2321 | to be thrown or leak information.Attackers may be able to modify the format string argument,
2322 | such that an exception is thrown. If this exception is left uncaught, it may crash the
2323 | application. Alternatively, if sensitive information is used within the unused arguments,
2324 | attackers may change the format string to reveal this information.
2325 | metadata:
2326 | cwe: "CWE-134: Use of Externally-Controlled Format String"
2327 | category: "security"
2328 | confidence: "HIGH"
2329 | severity: "ERROR"
2330 | - id: "find_sec_bugs.IMPROPER_UNICODE-1"
2331 | pattern-either:
2332 | - patterns:
2333 | - pattern-either:
2334 | - pattern: |
2335 | $S = (String $INPUT).$TRANSFORM(...);
2336 | ...
2337 | $S.$METHOD(...);
2338 | - pattern: "(String $INPUT).$TRANSFORM().$METHOD(...);"
2339 | - metavariable-regex:
2340 | metavariable: "$METHOD"
2341 | regex: "(equals|equalsIgnoreCase|indexOf)"
2342 | - metavariable-regex:
2343 | metavariable: "$TRANSFORM"
2344 | regex: "(toLowerCase|toUpperCase)"
2345 | - pattern: "java.text.Normalizer.normalize(...);"
2346 | - pattern: "java.net.IDN.toASCII(...);"
2347 | - pattern: "(URI $U).toASCIIString();"
2348 | languages:
2349 | - "java"
2350 | message: |
2351 | Improper Handling of Unicode Encoding
2352 | metadata:
2353 | cwe: "CWE-176: Improper Handling of Unicode Encoding"
2354 | category: "security"
2355 | confidence: "HIGH"
2356 | severity: "ERROR"
2357 | - id: "find_sec_bugs.MODIFICATION_AFTER_VALIDATION-1"
2358 | patterns:
2359 | - pattern: |
2360 | (java.util.regex.Pattern $Y).matcher($VAR);
2361 | ...
2362 | $VAR.$METHOD(...);
2363 | - metavariable-regex:
2364 | metavariable: "$METHOD"
2365 | regex: "(replace)"
2366 | languages:
2367 | - "java"
2368 | message: |
2369 | CERT: IDS11-J. Perform any string modifications before validation
2370 | metadata:
2371 | category: "security"
2372 | confidence: "HIGH"
2373 | severity: "WARNING"
2374 | - id: "find_sec_bugs.NORMALIZATION_AFTER_VALIDATION-1"
2375 | patterns:
2376 | - pattern: |
2377 | $Y = java.util.regex.Pattern.compile("[<>]");
2378 | ...
2379 | $Y.matcher($VAR);
2380 | ...
2381 | java.text.Normalizer.normalize($VAR, ...);
2382 | languages:
2383 | - "java"
2384 | message: |
2385 | IDS01-J. Normalize strings before validating them
2386 | metadata:
2387 | category: "security"
2388 | confidence: "HIGH"
2389 | severity: "WARNING"
2390 | - id: "find_sec_bugs.TEMPLATE_INJECTION_PEBBLE-1.TEMPLATE_INJECTION_FREEMARKER-1.TEMPLATE_INJECTION_VELOCITY-1"
2391 | pattern-either:
2392 | - patterns:
2393 | - pattern: "org.apache.velocity.app.Velocity.evaluate(..., $VAR)"
2394 | - pattern-not: "org.apache.velocity.app.Velocity.evaluate(..., \"...\")"
2395 | - patterns:
2396 | - pattern-not-inside: |
2397 | $C = (freemarker.template.Configuration $CFG).getTemplate("...");
2398 | ...
2399 | - pattern-inside: |
2400 | $C = (freemarker.template.Configuration $CFG).getTemplate($IN);
2401 | ...
2402 | - pattern: "$C.process(...)"
2403 | - patterns:
2404 | - pattern-inside: |
2405 | import com.mitchellbosecke.pebble.PebbleEngine;
2406 | ...
2407 | - pattern-inside: |
2408 | $C = $T.getTemplate($IN);
2409 | ...
2410 | - pattern-not-inside: |
2411 | $C = $T.getTemplate("...");
2412 | ...
2413 | - pattern: "$C.evaluate(...)"
2414 | languages:
2415 | - "java"
2416 | message: |
2417 | A malicious user in control of a template can run malicious code on the
2418 | server-side. Velocity templates should be seen as scripts.
2419 | metadata:
2420 | category: "security"
2421 | cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
2422 | severity: "ERROR"
2423 | - id: "find_sec_bugs.EXTERNAL_CONFIG_CONTROL-1"
2424 | patterns:
2425 | - pattern: |
2426 | $TAINTED = (HttpServletRequest $REQ).getParameter(...);
2427 | ...
2428 | (java.sql.Connection $CONN).setCatalog($TAINTED);
2429 | message: |
2430 | Allowing external control of system settings can disrupt service or cause an application to
2431 | behave in unexpected, and potentially malicious ways. An attacker could cause an error by
2432 | providing a nonexistent catalog name or connect to an unauthorized portion of the database.
2433 | languages:
2434 | - "java"
2435 | severity: "WARNING"
2436 | metadata:
2437 | category: "security"
2438 | cwe: "CWE-15: External Control of System or Configuration Setting"
2439 | technology:
2440 | - "java"
2441 | - id: "find_sec_bugs.INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE-1"
2442 | pattern-either:
2443 | - pattern: |
2444 | catch(Throwable $E) {
2445 | ...
2446 | $E.printStackTrace();
2447 | ...
2448 | }
2449 | - pattern: |
2450 | catch(Exception $E) {
2451 | ...
2452 | $E.printStackTrace();
2453 | ...
2454 | }
2455 | - pattern: |
2456 | catch(Error $E) {
2457 | ...
2458 | $E.printStackTrace();
2459 | ...
2460 | }
2461 | - pattern: |
2462 | catch(java.io.FileNotFoundException $E) {
2463 | ...
2464 | $E.printStackTrace();
2465 | ...
2466 | }
2467 | - pattern: |
2468 | catch(java.sql.SQLException $E) {
2469 | ...
2470 | $E.printStackTrace();
2471 | ...
2472 | }
2473 | - pattern: |
2474 | catch(java.net.BindException $E) {
2475 | ...
2476 | $E.printStackTrace();
2477 | ...
2478 | }
2479 | - pattern: |
2480 | catch(java.util.ConcurrentModificationException $E) {
2481 | ...
2482 | $E.printStackTrace();
2483 | ...
2484 | }
2485 | - pattern: |
2486 | catch(javax.naming.InsufficientResourcesException $E) {
2487 | ...
2488 | $E.printStackTrace();
2489 | ...
2490 | }
2491 | - pattern: |
2492 | catch(java.util.MissingResourceException $E) {
2493 | ...
2494 | $E.printStackTrace();
2495 | ...
2496 | }
2497 | - pattern: |
2498 | catch(java.util.jar.JarException $E) {
2499 | ...
2500 | $E.printStackTrace();
2501 | ...
2502 | }
2503 | - pattern: |
2504 | catch(java.security.acl.NotOwnerException $E) {
2505 | ...
2506 | $E.printStackTrace();
2507 | ...
2508 | }
2509 | - pattern: |
2510 | catch(OutOfMemoryError $E) {
2511 | ...
2512 | $E.printStackTrace();
2513 | ...
2514 | }
2515 | - pattern: |
2516 | catch(StackOverflowError $E) {
2517 | ...
2518 | $E.printStackTrace();
2519 | ...
2520 | }
2521 | message: |
2522 | The sensitive information may be valuable information on its own (such as a password), or it
2523 | may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use
2524 | error information provided by the server to launch another more focused attack. For example, an
2525 | attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the
2526 | installed application.
2527 | languages:
2528 | - "java"
2529 | severity: "WARNING"
2530 | metadata:
2531 | category: "security"
2532 | cwe: "CWE-209: Information Exposure Through an Error Message"
2533 | technology:
2534 | - "java"
2535 | - id: "find_sec_bugs.RPC_ENABLED_EXTENSIONS-1"
2536 | patterns:
2537 | - pattern-either:
2538 | - patterns:
2539 | - pattern-inside: |
2540 | XmlRpcServerConfigImpl $VAR = new org.apache.xmlrpc.server.XmlRpcServerConfigImpl();
2541 | ...
2542 | - pattern: "$VAR.setEnabledForExtensions(true);"
2543 | - patterns:
2544 | - pattern-inside: |
2545 | XmlRpcClientConfigImpl $VAR = new org.apache.xmlrpc.client.XmlRpcClientConfigImpl();
2546 | ...
2547 | - pattern: "$VAR.setEnabledForExtensions(true);"
2548 | languages:
2549 | - "java"
2550 | message: |
2551 | Enabling extensions in Apache XML RPC server or client can lead to deserialization
2552 | vulnerability which would allow an attacker to execute arbitrary code.
2553 | metadata:
2554 | category: "security"
2555 | cwe: "CWE-502: Deserialization of Untrusted Data"
2556 | severity: "WARNING"
2557 | - id: "find_sec_bugs.SAML_IGNORE_COMMENTS-1"
2558 | pattern: "(BasicParserPool $POOL).setIgnoreComments(false);"
2559 | languages:
2560 | - "java"
2561 | message: |
2562 | Ignoring XML comments in SAML may lead to authentication bypass
2563 | metadata:
2564 | cwe: "CWE-287: Improper Authentication"
2565 | category: "security"
2566 | severity: "WARNING"
2567 | - id: "find_sec_bugs.XML_DECODER-1"
2568 | patterns:
2569 | - pattern-either:
2570 | - patterns:
2571 | - pattern-inside: |
2572 | $D = new XMLDecoder($IN);
2573 | ...
2574 | - pattern-not-inside: |
2575 | $D = new XMLDecoder("...");
2576 | ...
2577 | - pattern: "$D.readObject()"
2578 | languages:
2579 | - "java"
2580 | message: |
2581 | Avoid using XMLDecoder to parse content from an untrusted source.
2582 | metadata:
2583 | category: "security"
2584 | cwe: "CWE-502: Deserialization of Untrusted Data"
2585 | severity: "WARNING"
2586 | - id: "find_sec_bugs.MALICIOUS_XSLT-1"
2587 | mode: "taint"
2588 | pattern-sources:
2589 | - patterns:
2590 | - pattern-either:
2591 | - patterns:
2592 | - pattern-inside: |
2593 | $FUNC(...,String $VAR, ...) {
2594 | ...
2595 | }
2596 | - pattern-either:
2597 | - pattern: "new FileInputStream(<... $VAR ...>);"
2598 | - pattern: "getClass().getResourceAsStream(<... $VAR ...>)"
2599 | - patterns:
2600 | - pattern-inside: |
2601 | class $CLZ {
2602 | String $X = "...";
2603 | ...
2604 | }
2605 | - pattern-inside: |
2606 | $FUNC(...,String $Y, ...) {
2607 | ...
2608 | }
2609 | - pattern-either:
2610 | - pattern: "new FileInputStream($X + $Y);"
2611 | - pattern: "getClass().getResourceAsStream($X + $Y)"
2612 | pattern-sinks:
2613 | - patterns:
2614 | - pattern-either:
2615 | - pattern-inside: |-
2616 | (javax.xml.transform.TransformerFactory $T).newTransformer($SRC, ...)
2617 | - pattern-inside: |-
2618 | (javax.xml.transform.Transformer $T).transform($SRC, ...)
2619 | - pattern: "$SRC"
2620 | languages:
2621 | - "java"
2622 | message: |
2623 | It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker
2624 | can control the content or the source of the style sheet, he might be able to trigger remote
2625 | code execution.
2626 | metadata:
2627 | cwe": "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
2628 | Traversal')"
2629 | category: "security"
2630 | severity: "WARNING"
2631 | - id: "find_sec_bugs.XPATH_INJECTION-1"
2632 | patterns:
2633 | - pattern-either:
2634 | - pattern-inside: |-
2635 | import javax.xml.xpath.*; ...
2636 | - pattern-inside: |-
2637 | import javax.xml.xpath.Xpath; ...
2638 | - pattern-either:
2639 | - patterns:
2640 | - pattern: "(XPath $X).compile($ARG)"
2641 | - pattern-not: "(XPath $X).compile(\"...\")"
2642 | - patterns:
2643 | - pattern: "(XPath $X).evaluate($ARG)"
2644 | - pattern-not: "(XPath $X).evaluate(\"...\")"
2645 | languages:
2646 | - "java"
2647 | message: |
2648 | The input values included in SQL queries need to be passed in safely. Bind
2649 | variables in prepared statements can be used to easily mitigate the risk of
2650 | SQL injection.
2651 | metadata:
2652 | category: "security"
2653 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2654 | severity: "ERROR"
2655 | - id: "find_sec_bugs.XSS_REQUEST_WRAPPER-1"
2656 | patterns:
2657 | - pattern-inside: |
2658 | class $CLASS extends HttpServletRequestWrapper {
2659 | ...
2660 | }
2661 | - pattern: "stripXSS(...) { ... }"
2662 | languages:
2663 | - "java"
2664 | message: |
2665 | Avoid using custom XSS filtering. Please use standard sanitization functions.
2666 | metadata:
2667 | category: "security"
2668 | cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site
2669 | Scripting')"
2670 | severity: "INFO"
2671 | - id: "find_sec_bugs.WICKET_XSS1-1"
2672 | patterns:
2673 | - pattern: "(org.apache.wicket.markup.html.basic.Label $X).setEscapeModelStrings(false);"
2674 | languages:
2675 | - "java"
2676 | message: |
2677 | Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS).
2678 | metadata:
2679 | category: "security"
2680 | cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site
2681 | Scripting')"
2682 | severity: "WARNING"
2683 | - id: "find_sec_bugs.XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER-1"
2684 | mode: "taint"
2685 | pattern-sources:
2686 | - patterns:
2687 | - pattern-inside: |-
2688 | $FUNC(..., HttpServletRequest $REQ, ...) {...}
2689 | - pattern: "$REQ.getParameter(...);"
2690 | pattern-sanitizers:
2691 | - patterns:
2692 | - pattern-inside: |-
2693 | org.owasp.encoder.Encode.forHtml($TAINTED);
2694 | - pattern: "$TAINTED"
2695 | pattern-sinks:
2696 | - patterns:
2697 | - pattern-inside: |-
2698 | $FUNC(..., HttpServletResponse $RES, ...) {...}
2699 | - pattern-inside: |
2700 | $WRITER = $RES.getWriter();
2701 | ...
2702 | - pattern: "$WRITER.write($DATA,...);"
2703 | - pattern: "$DATA"
2704 | - patterns:
2705 | - pattern-inside: |-
2706 | $FUNC(..., HttpServletResponse $RES, ...) {...}
2707 | - pattern: "$RES.getWriter().write($DATA,...);"
2708 | - pattern: "$DATA"
2709 | message: |
2710 | Servlet reflected cross site scripting vulnerability
2711 | languages:
2712 | - "java"
2713 | severity: "WARNING"
2714 | metadata:
2715 | cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation"
2716 | category: "security"
2717 | technology:
2718 | - "java"
2719 | - id: "find_sec_bugs.XSS_SERVLET-1"
2720 | mode: "taint"
2721 | pattern-sources:
2722 | - patterns:
2723 | - pattern-inside: |-
2724 | $FUNC(..., HttpServletRequest $REQ, ...) {...}
2725 | - pattern: "$REQ.getParameter(...);"
2726 | pattern-sanitizers:
2727 | - patterns:
2728 | - pattern-inside: |-
2729 | org.owasp.encoder.Encode.forHtml($TAINTED);
2730 | - pattern: "$TAINTED"
2731 | pattern-sinks:
2732 | - patterns:
2733 | - pattern-inside: |-
2734 | $FUNC(..., HttpServletResponse $RES, ...) {...}
2735 | - pattern-inside: |
2736 | $WRITER = $RES.getWriter();
2737 | ...
2738 | - pattern: "$WRITER.write($DATA,...);"
2739 | - pattern: "$DATA"
2740 | - patterns:
2741 | - pattern-inside: |-
2742 | $FUNC(..., HttpServletResponse $RES, ...) {...}
2743 | - pattern: "$RES.getWriter().write($DATA,...);"
2744 | - pattern: "$DATA"
2745 | message: |
2746 | A potential XSS was found. It could be used to execute unwanted JavaScript in a
2747 | client's browser.
2748 | languages:
2749 | - "java"
2750 | metadata:
2751 | cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site
2752 | Scripting')"
2753 | category: "security"
2754 | severity: "WARNING"
2755 | - id: "find_sec_bugs.XSS_SERVLET-2.XSS_SERVLET_PARAMETER-1"
2756 | pattern-either:
2757 | - patterns:
2758 | - pattern-inside: |-
2759 | $TYPE $FUNC(..., ServletRequest $REQ, ...) { ... }
2760 | - pattern-either:
2761 | - pattern: "$REQ.getParameter(...);"
2762 | - pattern: "$REQ.getParameterValues();"
2763 | - pattern: "$REQ.getParameterMap(...);"
2764 | - pattern: "$REQ.getParameterNames();"
2765 | - patterns:
2766 | - pattern-inside: |-
2767 | $TYPE $FUNC(..., HttpServletRequest $SREQ, ...) { ... }
2768 | - pattern-either:
2769 | - pattern: "$SREQ.getRequestedSessionId();"
2770 | - pattern: "$SREQ.getQueryString();"
2771 | - pattern: "$SREQ.getParameter(...);"
2772 | - pattern: "$SREQ.getParameterValues();"
2773 | - pattern: "$SREQ.getParameterMap(...);"
2774 | - pattern: "$SREQ.getParameterNames();"
2775 | - patterns:
2776 | - pattern: "$SREQ.getHeader($HEADER);"
2777 | - metavariable-regex:
2778 | metavariable: "$HEADER"
2779 | regex: "(?i)(Host|Referer|User-Agent)"
2780 | message: |
2781 | The Servlet can read GET and POST parameters from various methods. The value obtained should be
2782 | considered unsafe. You may need to validate or sanitize those values before passing them to
2783 | sensitive APIs
2784 | languages:
2785 | - "java"
2786 | severity: "WARNING"
2787 | metadata:
2788 | cwe: "CWE-20: Improper Input Validation"
2789 | category: "security"
2790 | technology:
2791 | - "java"
2792 | - id: "find_sec_bugs.XXE_SAXPARSER-1"
2793 | patterns:
2794 | - pattern-inside: |
2795 | $SF = SAXParserFactory.newInstance();
2796 | ...
2797 | - pattern-not-inside: |
2798 | $SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2799 | ...
2800 | - pattern-not-inside: |
2801 | $SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
2802 | ...
2803 | - pattern-inside: |
2804 | $P = $SFP.newSAXParser();
2805 | ...
2806 | - pattern: "$P.parse(...);"
2807 | languages:
2808 | - "java"
2809 | message: |
2810 | XML External Entity (XXE) attacks can occur when an XML parser supports XML
2811 | entities while processing XML received from an untrusted source.
2812 | metadata:
2813 | category: "security"
2814 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2815 | severity: "ERROR"
2816 | - id: "find_sec_bugs.XXE_DTD_TRANSFORM_FACTORY-1.XXE_XSLT_TRANSFORM_FACTORY-1"
2817 | patterns:
2818 | - pattern-inside: |-
2819 | import javax.xml.transform.*; ...
2820 | - pattern-inside: |
2821 | $T = $FACT.newTransformer();
2822 | ...
2823 | - pattern-not-inside: |
2824 | $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
2825 | ...
2826 | - pattern-not-inside: |
2827 | $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
2828 | ...
2829 | - pattern-not-inside: |
2830 | $T.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2831 | ...
2832 | - pattern: "$T.transform(...)"
2833 | languages:
2834 | - "java"
2835 | message: |
2836 | XML External Entity (XXE) attacks can occur when an XML parser supports XML
2837 | entities while processing XML received from an untrusted source.
2838 | metadata:
2839 | category: "security"
2840 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2841 | severity: "ERROR"
2842 | - id: "find_sec_bugs.XXE_XMLREADER-1"
2843 | patterns:
2844 | - pattern-inside: |
2845 | $R = XMLReaderFactory.createXMLReader();
2846 | ...
2847 | - pattern-not-inside: |
2848 | $R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2849 | ...
2850 | - pattern: "$R.parse(...);"
2851 | languages:
2852 | - "java"
2853 | message: |
2854 | XML External Entity (XXE) attacks can occur when an XML parser supports XML
2855 | entities while processing XML received from an untrusted source.
2856 | metadata:
2857 | category: "security"
2858 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2859 | severity: "ERROR"
2860 | - id: "find_sec_bugs.XXE_XMLSTREAMREADER-1"
2861 | patterns:
2862 | - pattern-inside: |
2863 | $SF = XMLInputFactory.newFactory();
2864 | ...
2865 | - pattern-not-inside: |
2866 | $SF.setProperty(XMLInputFactory.SUPPORT_DTD, false);
2867 | ...
2868 | - pattern-not-inside: |
2869 | $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
2870 | ...
2871 | - pattern: "$SF.createXMLStreamReader(...)"
2872 | languages:
2873 | - "java"
2874 | message: |
2875 | XML External Entity (XXE) attacks can occur when an XML parser supports XML
2876 | entities while processing XML received from an untrusted source.
2877 | metadata:
2878 | category: "security"
2879 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2880 | severity: "ERROR"
2881 | - id: "find_sec_bugs.XXE_XPATH-1.XXE_DOCUMENT-1"
2882 | patterns:
2883 | - pattern-inside: |
2884 | $DF = df.newDocumentBuilder();
2885 | ...
2886 | - pattern-not-inside: |
2887 | $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
2888 | ...
2889 | - pattern-not-inside: |
2890 | $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
2891 | ...
2892 | - pattern-not-inside: |
2893 | $DF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2894 | ...
2895 | - pattern-not-inside: |
2896 | $DF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
2897 | ...
2898 | - pattern: "$SF.newDocumentBuilder(...)"
2899 | languages:
2900 | - "java"
2901 | message: |
2902 | XML External Entity (XXE) attacks can occur when an XML parser supports XML
2903 | entities while processing XML received from an untrusted source.
2904 | metadata:
2905 | category: "security"
2906 | cwe: "CWE-611: Improper Restriction of XML External Entity Reference ('XXE')"
2907 | severity: "ERROR"
2908 |
--------------------------------------------------------------------------------
/analyzers/find_unicode_control2.py:
--------------------------------------------------------------------------------
1 | """
2 | This file is part of Betterscan CE (Community Edition).
3 |
4 | Betterscan is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | Betterscan is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with Betterscan. If not, see .
16 |
17 | Originally licensed under the BSD-3-Clause license with parts changed under
18 | LGPL v2.1 with Commons Clause.
19 | See the original LICENSE file for details.
20 |
21 | Based on https://github.com/siddhesh/find-unicode-control/ under BSD-3-Clause license
22 |
23 | Copyright (c) 2021, Red Hat
24 | All rights reserved.
25 |
26 | Redistribution and use in source and binary forms, with or without
27 | modification, are permitted provided that the following conditions are met:
28 |
29 | Redistributions of source code must retain the above copyright notice, this
30 | list of conditions and the following disclaimer.
31 |
32 | Redistributions in binary form must reproduce the above copyright notice,
33 | this list of conditions and the following disclaimer in the documentation
34 | and/or other materials provided with the distribution.
35 |
36 | Neither the name of HPCProject, Serge Guelton nor the names of its
37 | contributors may be used to endorse or promote products derived from this
38 | software without specific prior written permission.
39 |
40 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
41 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
44 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
47 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
49 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 |
51 | """
52 | #!/usr/bin/env python3
53 | """Find unicode control characters in source files
54 |
55 | By default the script takes one or more files or directories and looks for
56 | unicode control characters in all text files. To narrow down the files, provide
57 | a config file with the -c command line, defining a scan_exclude list, which
58 | should be a list of regular expressions matching paths to exclude from the scan.
59 |
60 | There is a second mode enabled with -p which when set to 'all', prints all
61 | control characters and when set to 'bidi', prints only the 9 bidirectional
62 | control characters.
63 | """
64 |
65 |
66 | import sys, os, argparse, re, unicodedata, subprocess
67 | import importlib
68 | import json
69 | from stat import *
70 |
71 | def _unicode(line, encoding):
72 | if isinstance(line, str):
73 | return line
74 | return line.decode(encoding)
75 |
76 | import platform
77 | if platform.python_version()[0] == '2':
78 | _chr = chr
79 | do_unicode = str
80 | else:
81 | _chr = chr
82 | do_unicode = _unicode
83 |
84 | scan_exclude = [r'\.git/', r'\.hg/', r'\.desktop$', r'ChangeLog$', r'NEWS$',
85 | r'\.ppd$', r'\.txt$', r'\.directory$']
86 | scan_exclude_mime = [r'text/x-po$', r'text/x-tex$', r'text/x-troff$',
87 | r'text/html$']
88 | verbose_mode = False
89 |
90 | # Print to stderr in verbose mode.
91 | def eprint(*args, **kwargs):
92 | if verbose_mode:
93 | print(*args, file=sys.stderr, **kwargs)
94 |
95 | # Decode a single latin1 line.
96 | def decodeline(inf):
97 | return do_unicode(inf, 'utf-8')
98 |
99 | # Make a text string from a file, attempting to decode from latin1 if necessary.
100 | # Other non-utf-8 locales are not supported at the moment.
101 | def getfiletext(filename):
102 | text = None
103 | with open(filename) as infile:
104 | try:
105 | if detailed_mode:
106 | return [decodeline(inf) for inf in infile]
107 | except Exception as e:
108 | eprint('%s: %s' % (filename, e))
109 | return None
110 |
111 | try:
112 | text = decodeline(''.join(infile))
113 | except UnicodeDecodeError:
114 | eprint('%s: Retrying with latin1' % filename)
115 | try:
116 | text = ''.join([decodeline(inf) for inf in infile])
117 | except Exception as e:
118 | eprint('%s: %s' % (filename, e))
119 | if text:
120 | return set(text)
121 | else:
122 | return None
123 |
124 | def analyze_text_detailed(filename, text, disallowed, msg):
125 | line = 0
126 | warned = False
127 | for t in text:
128 | line = line + 1
129 | subset = [c for c in t if chr(ord(c)) in disallowed]
130 | if subset:
131 | #print('%s:%d %s: %s' % (filename, line, msg, subset))
132 | out = dict()
133 | out[str("I001")]=msg
134 | out[str("line")]=int(line)
135 | #json.dumps('{"I001":"%s","line": %i}' % (msg,line))
136 | print(json.dumps(out))
137 | if not warned:
138 | eprint('%s: OK' % filename)
139 |
140 | # Look for disallowed characters in the text. We reduce all characters into a
141 | # set to speed up analysis. FIXME: Add a slow mode to get line numbers in files
142 | # that have these disallowed chars.
143 | def analyze_text(filename, text, disallowed, msg):
144 | if detailed_mode:
145 | analyze_text_detailed(filename, text, disallowed, msg)
146 | return
147 |
148 | if not text.isdisjoint(disallowed):
149 | #print('%s: %s: %s' % (filename, msg, text & disallowed))
150 | print('{"I001":"%s"}' % (msg))
151 | else:
152 | eprint('%s: OK' % filename)
153 |
154 | def should_read(f):
155 | args = ['file', '--mime-type', f]
156 | proc = subprocess.Popen(args, stdout=subprocess.PIPE)
157 | m = [decodeline(x[:-1]) for x in proc.stdout][0].split(':')[1].strip()
158 | # Fast check, just the file name.
159 | if [e for e in scan_exclude if re.search(e, f)]:
160 | return False
161 |
162 | # Slower check, mime type.
163 | if not 'text/' in m \
164 | or [e for e in scan_exclude_mime if re.search(e, m)]:
165 | return False
166 | return True
167 |
168 | # Get file text and feed into analyze_text.
169 | def analyze_file(f, disallowed, msg):
170 | eprint('%s: Reading file' % f)
171 | if should_read(f):
172 | text = getfiletext(f)
173 | if text:
174 | analyze_text(f, text, disallowed, msg)
175 | else:
176 | eprint('%s: SKIPPED' % f)
177 |
178 | # Actual implementation of the recursive descent into directories.
179 | def analyze_any(p, disallowed, msg):
180 | #mode = os.stat(p).st_mode
181 | #if S_ISDIR(mode):
182 | # analyze_dir(p, disallowed, msg)
183 | #elif S_ISREG(mode):
184 | analyze_file(p, disallowed, msg)
185 | #else:
186 | # eprint('%s: UNREADABLE' % p)
187 |
188 | # Recursively analyze files in the directory.
189 | def analyze_dir(d, disallowed, msg):
190 | for f in os.listdir(d):
191 | analyze_any(os.path.join(d, f), disallowed, msg)
192 |
193 | def analyze_paths(paths, disallowed, msg):
194 | for p in paths:
195 | analyze_any(p, disallowed, msg)
196 |
197 | # All control characters. We omit the ascii control characters.
198 | def nonprint_unicode(c):
199 | cat = unicodedata.category(c)
200 | if cat.startswith('C') and cat != 'Cc':
201 | return True
202 | return False
203 |
204 | if __name__ == '__main__':
205 | parser = argparse.ArgumentParser(description="Look for Unicode control characters")
206 | parser.add_argument('path', metavar='path', nargs='+',
207 | help='Sources to analyze')
208 | parser.add_argument('-p', '--nonprint', required=False,
209 | type=str, choices=['all', 'bidi'],
210 | help='Look for either all non-printable unicode characters or bidirectional control characters.')
211 | parser.add_argument('-v', '--verbose', required=False, action='store_true',
212 | help='Verbose mode.')
213 | parser.add_argument('-d', '--detailed', required=False, action='store_true',
214 | help='Print line numbers where characters occur.')
215 | parser.add_argument('-t', '--notests', required=False,
216 | action='store_true', help='Exclude tests (basically test.* as a component of path).')
217 | parser.add_argument('-c', '--config', required=False, type=str,
218 | help='Configuration file to read settings from.')
219 |
220 | args = parser.parse_args()
221 | verbose_mode = args.verbose
222 | detailed_mode = args.detailed
223 |
224 | if not args.nonprint:
225 | # Formatting control characters in the unicode space. This includes the
226 | # bidi control characters.
227 | disallowed = set(_chr(c) for c in range(sys.maxunicode) if \
228 | unicodedata.category(_chr(c)) == 'Cf')
229 |
230 | msg = 'unicode control characters'
231 | elif args.nonprint == 'all':
232 | # All control characters.
233 | disallowed = set(_chr(c) for c in range(sys.maxunicode) if \
234 | nonprint_unicode(_chr(c)))
235 |
236 | msg = 'disallowed characters'
237 | else:
238 | # Only bidi control characters.
239 | disallowed = set([
240 | _chr(0x202a), _chr(0x202b), _chr(0x202c), _chr(0x202d), _chr(0x202e),
241 | _chr(0x2066), _chr(0x2067), _chr(0x2068), _chr(0x2069)])
242 | msg = 'bidirectional control characters'
243 |
244 | if args.config:
245 | spec = importlib.util.spec_from_file_location("settings", args.config)
246 | settings = importlib.util.module_from_spec(spec)
247 | spec.loader.exec_module(settings)
248 | if hasattr(settings, 'scan_exclude'):
249 | scan_exclude = scan_exclude + settings.scan_exclude
250 | if hasattr(settings, 'scan_exclude_mime'):
251 | scan_exclude_mime = scan_exclude_mime + settings.scan_exclude_mime
252 |
253 | if args.notests:
254 | scan_exclude = scan_exclude + [r'/test[^/]+/']
255 |
256 | analyze_paths(args.path, disallowed, msg)
257 |
--------------------------------------------------------------------------------
/analyzers/json_reporter.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Betterscan CE (Community Edition).
3 | *
4 | * Betterscan is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Affero General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Betterscan is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Affero General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Affero General Public License
15 | * along with Betterscan. If not, see .
16 | *
17 | * Originally licensed under the BSD-3-Clause license with parts changed under
18 | * LGPL v2.1 with Commons Clause.
19 | * See the original LICENSE file for details.
20 | */
21 | "use strict";
22 | /*JSON reporter module, which will just return a JSON dump of the errors found in a given file*/
23 | module.exports = {
24 | reporter: function (res) {
25 | process.stdout.write(JSON.stringify(res,undefined,true));
26 | }
27 | };
--------------------------------------------------------------------------------
/cli-html.sh:
--------------------------------------------------------------------------------
1 | # Ensure CODE_DIR is defined as the current directory
2 | export CODE_DIR=$(pwd)
3 | cd "$CODE_DIR"
4 |
5 | # Set environment variables and Docker options
6 | ENV_VARS="-e CODE_DIR=$CODE_DIR -e OPENAI_GPT_API"
7 | VOLUME_MOUNT="-v ${CODE_DIR}:${CODE_DIR}"
8 | DOCKER_IMAGE="tcosolutions/betterscan-worker-cli:latest"
9 | SAFE_DIR_CMD="git config --global --add safe.directory $CODE_DIR"
10 | GIT_BRANCH_CMD="git rev-parse --abbrev-ref HEAD"
11 |
12 | # Define a function to run Docker commands
13 | run_docker() {
14 | docker run $ENV_VARS $VOLUME_MOUNT -ti $DOCKER_IMAGE /bin/sh -c "cd $CODE_DIR && $SAFE_DIR_CMD && $1"
15 | }
16 |
17 | # Initialize checkmate and analyze the git repository
18 | run_docker "checkmate init --backend sqlite --backend-opts \"sqlite:////${CODE_DIR}/.checkmate/database.db\""
19 | run_docker "checkmate git init --backend sqlite --backend-opts \"sqlite:////${CODE_DIR}/.checkmate/database.db\""
20 | run_docker "checkmate git analyze --branch \`$GIT_BRANCH_CMD\`"
21 | run_docker "checkmate issues html"
22 |
--------------------------------------------------------------------------------
/cli.sh:
--------------------------------------------------------------------------------
1 | # Ensure CODE_DIR is defined as the current directory
2 | export CODE_DIR=$(pwd)
3 | cd "$CODE_DIR"
4 |
5 | # Set environment variables and Docker options
6 | ENV_VARS="-e CODE_DIR=$CODE_DIR -e OPENAI_GPT_API"
7 | VOLUME_MOUNT="-v ${CODE_DIR}:${CODE_DIR}"
8 | DOCKER_IMAGE="tcosolutions/betterscan-worker-cli:latest"
9 | SAFE_DIR_CMD="git config --global --add safe.directory $CODE_DIR"
10 | GIT_BRANCH_CMD="git rev-parse --abbrev-ref HEAD"
11 |
12 | # Define a function to run Docker commands
13 | run_docker() {
14 | docker run $ENV_VARS $VOLUME_MOUNT -ti $DOCKER_IMAGE /bin/sh -c "cd $CODE_DIR && $SAFE_DIR_CMD && $1"
15 | }
16 |
17 | # Initialize checkmate and analyze the git repository
18 | run_docker "checkmate init --backend sqlite --backend-opts \"sqlite:////${CODE_DIR}/.checkmate/database.db\""
19 | run_docker "checkmate git init --backend sqlite --backend-opts \"sqlite:////${CODE_DIR}/.checkmate/database.db\""
20 | run_docker "checkmate git analyze --branch \`$GIT_BRANCH_CMD\`"
21 | run_docker "checkmate issues"
22 |
--------------------------------------------------------------------------------
/data/.empty:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcosolutions/betterscan/4d30e06f13755e143836506a6797acf7f589e24b/data/.empty
--------------------------------------------------------------------------------
/docker/docker/worker-cli/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12-slim AS builder
2 |
3 | ARG DEBIAN_FRONTEND=noninteractive
4 | ENV SHELL=/bin/bash
5 |
6 |
7 |
8 | RUN apt-get update && apt-get install -y ca-certificates curl tar libssl-dev git ssh rubygems python3-pip pipenv unzip jq gcc build-essential
9 |
10 |
11 | # Install Go
12 | RUN GO_JSON=$(curl -s https://go.dev/dl/?mode=json) && \
13 | GO_LATEST=$(echo "$GO_JSON" | jq -r '.[0].version') && \
14 | ARCH=$(uname -m) && \
15 | case $ARCH in \
16 | x86_64) GO_ARCH="amd64" ;; \
17 | aarch64) GO_ARCH="arm64" ;; \
18 | armv7l) GO_ARCH="armv6l" ;; \
19 | *) echo "Unsupported architecture: $ARCH"; exit 1 ;; \
20 | esac && \
21 | GO_URL="https://dl.google.com/go/${GO_LATEST}.linux-${GO_ARCH}.tar.gz" && \
22 | curl -O $GO_URL && \
23 | tar -C /usr/local -xzf ${GO_LATEST}.linux-${GO_ARCH}.tar.gz && \
24 | rm ${GO_LATEST}.linux-${GO_ARCH}.tar.gz
25 |
26 | # Set up Go environment variables
27 | ENV PATH=$PATH:/usr/local/go/bin
28 |
29 | # Install Ruby and npm packages
30 | RUN gem install brakeman
31 |
32 | RUN python3 -m venv venv && pip install pip && pip install bandit && pip install checkmate5 && pip install aigraphcodescan
33 |
34 | # Clone and install other repositories
35 | RUN git clone https://github.com/tcosolutions/betterscan.git /srv/betterscan
36 |
37 | # Set up additional tools
38 | RUN curl https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash && \
39 | curl https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | bash
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------