├── .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 |
4 | 5 | Betterscan 6 | 7 |
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 | --------------------------------------------------------------------------------