Skip to content

Instantly share code, notes, and snippets.

@jerinisready
Last active December 16, 2025 12:30
Show Gist options
  • Select an option

  • Save jerinisready/f588121fb487feb7edbfe9ee2be11a0e to your computer and use it in GitHub Desktop.

Select an option

Save jerinisready/f588121fb487feb7edbfe9ee2be11a0e to your computer and use it in GitHub Desktop.
Please dont reuse, without actuall knowledge of license. This is not really recommedned for enterprices. I dont know which licenses these containse. This is just for Experimental purpose
rules:
- id: ruby_ftp_rule-AvoidTaintedFTPCall
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
pattern-sinks:
- pattern-either:
- pattern: Net::FTP.$X(...)
- patterns:
- pattern-inside: '$FTP = Net::FTP.$OPEN(...)
...
$FTP.$METHOD(...)
'
- pattern: $FTP.$METHOD(...)
message: "The application was found calling the Net::FTP modules methods with\n\
user supplied input. A malicious actor could use this to modify or access files\n\
they should not have access to.\n\nDirectly incorporating user-controlled input\
\ from `params`, `cookies`, \nor `request.env` into FTP commands or connection\
\ setups can lead to \nvarious security vulnerabilities, including Remote Code\
\ Execution \n(RCE), unauthorized file access, and data exfiltration. It's crucial\
\ \nto validate, sanitize, and, where possible, avoid using user-controlled \n\
data in sensitive operations like FTP transactions. Ensure that any input \nused\
\ in FTP operations is strictly controlled and validated against \nexpected patterns.\n\
\nRemediation Strategy:\nTo mitigate these risks, ensure that all user-provided\
\ input is strictly \nvalidated and sanitized before being used in FTP operations.\
\ \n- Verify the format and content of the input to ensure it meets expected \n\
criteria.\n- Use allowlists to restrict the input to known safe values.\n- Employ\
\ built-in security features of the programming language or \nframework to escape\
\ or safely handle user input.\n\nSecure Code Example:\n```\nfilename = params[:filename]\n\
# Validate the filename to ensure it's a known, safe file\nraise \"Invalid filename\"\
\ unless filename =~ /\\A[\\w]+\\.\\w+\\z/\n\nNet::FTP.open('example.com', 'user',\
\ 'password') do |ftp|\n # Proceed with the FTP operation using the validated\
\ and sanitized filename\n ftp.getbinaryfile(filename, \"local_#{filename}\"\
, 1024)\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-76
shortDescription: Improper neutralization of equivalent special elements
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-ftp-call.yaml
category: security
security-severity: MEDIUM
technology:
- ruby
- rails
- id: ruby_crypto_rule-WeakHashesMD5
message: "The MD5 hashing algorithm is considered cryptographically weak and \n\
vulnerable to collision attacks, where two different inputs generate \nthe same\
\ output hash. When used for hashing sensitive data, attackers \ncan exploit this\
\ weakness to generate collisions, allowing them to bypass \nsecurity checks or\
\ masquerade malicious data as legitimate. This \nvulnerability is particularly\
\ critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates,\
\ and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability,\
\ replace the MD5 hashing algorithm with \nstronger cryptographic hash functions,\
\ such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security\
\ and are resistant to \ncollision attacks, making them suitable for cryptographic\
\ purposes in \nmodern applications.\n\nSecure Code example:\n```\nrequire 'openssl'\n\
\ndata = \"sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\n\
hash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3\
\ (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\n\
hex_hash2 = digest.hexdigest(data)\n```\n"
metadata:
shortDescription: Use of weak hash
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-328
security-severity: MEDIUM
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-md5.yaml
- https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575
technology:
- ruby
languages:
- ruby
severity: WARNING
pattern-either:
- pattern: Digest::MD5.base64digest $X
- pattern: Digest::MD5.hexdigest $X
- pattern: Digest::MD5.digest $X
- pattern: Digest::MD5.new
- pattern: OpenSSL::Digest::MD5.base64digest $X
- pattern: OpenSSL::Digest::MD5.hexdigest $X
- pattern: OpenSSL::Digest::MD5.digest $X
- pattern: OpenSSL::Digest::MD5.new
- id: ruby_crypto_rule-InsufficientRSAKeySize
message: "The RSA key size $SIZE is insufficent by NIST standards. It is \nrecommended\
\ to use a key length of 2048 or higher. The RSA algorithm, \nbeing widely used\
\ for secure data transmission, relies on key size \nfor its security. Smaller\
\ key sizes (e.g., 1024 bits and below) are \nmore susceptible to brute-force\
\ attacks, where an attacker uses \ncomputational power to decrypt data or forge\
\ signatures. \n\nTo address this security concern, ensure that all RSA keys are\
\ \ngenerated with a size of 2048 bits or more.\n\nFolowing is a secure code example:\n\
```\nrequire 'openssl'\n\n# Generate a new RSA key of 2048 bits\nrsa_key = OpenSSL::PKey::RSA.new(2048)\n\
\n# To export the RSA key\nprivate_key = rsa_key.to_pem\npublic_key = rsa_key.public_key.to_pem\n\
```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
shortDescription: Inadequate encryption strength
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-326
technology:
- ruby
security-severity: MEDIUM
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/insufficient-rsa-key-size.yaml
- https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf
patterns:
- pattern-either:
- pattern: OpenSSL::PKey::RSA.generate($SIZE,...)
- pattern: OpenSSL::PKey::RSA.new($SIZE, ...)
- patterns:
- pattern-either:
- patterns:
- pattern-inside: '$ASSIGN = $SIZE
...
'
- pattern-either:
- pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...)
- pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...)
- patterns:
- pattern-inside: 'def $METHOD1(...)
...
$ASSIGN = $SIZE
...
end
...
'
- pattern-either:
- pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...)
- pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...)
- metavariable-comparison:
metavariable: $SIZE
comparison: $SIZE < 2048
- id: ruby_crypto_rule-WeakHashesSHA1
message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic\
\ applications due to its vulnerability to collision attacks,\nwhere two different\
\ inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks\
\ undermines the security of\ncryptographic operations, allowing attackers to\
\ forge signatures or\nmanipulate data without detection. This poses significant\
\ risks in\nauthentication systems, data integrity validations, and secure\ncommunications.\
\ \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \n\
algorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3.\
\ These algorithms offer significantly improved security and \nare resistant to\
\ collision attacks, making them suitable for cryptographic \npurposes in modern\
\ applications.\n\nSecure Code example : \n``` \nrequire 'openssl'\n\ndata = \"\
sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\n\
hash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3\
\ (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\n\
hex_hash2 = digest.hexdigest(data)\n```\n"
metadata:
shortDescription: Use of weak hash
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-328
security-severity: MEDIUM
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-sha1.yaml
- https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
- https://shattered.io/
technology:
- ruby
languages:
- ruby
severity: WARNING
pattern-either:
- pattern: Digest::SHA1.$FUNC
- pattern: OpenSSL::Digest::SHA1.$FUNC
- pattern: OpenSSL::HMAC.$FUNC("sha1",...)
- id: ruby_ssl_rule-SSLModeNoVerify
pattern: OpenSSL::SSL::VERIFY_NONE
fix-regex:
regex: VERIFY_NONE
replacement: VERIFY_PEER
message: "The application was found using `OpenSSL::SSL::VERIFY_NONE`.\nThis effectively\
\ disables the validation of TLS certificates.\n\nThis allows for an adversary\
\ who is in between the application and the \ntarget host to intercept potentially\
\ sensitive information or transmit \nmalicious data.\n\nTo remediate this issue,\
\ use 'OpenSSL::SSL::VERIFY_PEER' instead.\n"
severity: WARNING
languages:
- ruby
metadata:
cwe: CWE-295
shortDescription: Improper certificate validation
owasp:
- A3:2017-Sensitive Data Exposure
- A07:2021-Identification and Authentication Failures
category: security
security-severity: MEDIUM
technology:
- ruby
references:
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/ssl-mode-no-verify.yaml
- id: ruby_ssl_rule-ForceSSLFalse
pattern: config.force_ssl = false
fix-regex:
regex: =\s*false
replacement: = true
message: "The application was found setting `force_ssl` to `false`. This setting\n\
can expose the application to the risk of network\ninterception of unencrypted\
\ traffic. Enabling `force_ssl` by setting \n`config.force_ssl = true` in the\
\ application's configuration, specifically \nwithin `config/environments/production.rb`,\
\ forces the use of HTTPS, \nencrypting data in transit and safeguarding against\
\ eavesdropping or data \ntampering. \n"
languages:
- ruby
severity: WARNING
metadata:
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A04:2021-Insecure Design
security-severity: MEDIUM
technology:
- ruby
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/force-ssl-false.yaml
- id: ruby_escaping_rule-JSONEntityEscape
pattern-either:
- pattern: 'ActiveSupport.escape_html_entities_in_json = false
'
- pattern: 'config.active_support.escape_html_entities_in_json = false
'
message: "This rule checks if HTML escaping is globally disabled for JSON output,\
\ \nwhich can lead to Cross-Site Scripting (XSS) vulnerabilities. \nXSS attacks\
\ allow attackers to inject malicious scripts into web pages \nviewed by other\
\ users, compromising the integrity and confidentiality \nof user data. When HTML\
\ escaping is disabled, special HTML characters \nin JSON output are not converted\
\ to their entity equivalents, making \nit possible for an attacker to inject\
\ executable scripts into the web \napplication's output. \n\nTo mitigate this\
\ risk, ensure that HTML escaping is enabled when \ngenerating JSON output, particularly\
\ in web applications \nthat dynamically insert user-generated content into the\
\ DOM.\n\nSecure Code Example:\n```\n# For an initializer configuration (e.g.,\
\ in config/initializers/active_support.rb)\n# Enable HTML entity escaping in\
\ JSON to prevent XSS\nActiveSupport.escape_html_entities_in_json = true\n\n#\
\ For application-wide configuration (e.g., in config/application.rb)\nmodule\
\ YourApplication\n class Application < Rails::Application\n # Enable HTML\
\ entity escaping in JSON to prevent XSS\n config.active_support.escape_html_entities_in_json\
\ = true\n end\nend\n```\n"
languages:
- ruby
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
technology:
- rails
references:
- https://owasp.org/Top10/A03_2021-Injection
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/json-entity-escape.yaml
severity: WARNING
- id: ruby_file_rule-CheckRenderLocalFileInclude
mode: taint
pattern-sources:
- patterns:
- pattern: params[...]
pattern-sinks:
- patterns:
- pattern-either:
- pattern: 'render ..., file: $X
'
- pattern: 'render ..., inline: $X
'
- pattern: 'render ..., template: $X
'
- pattern: 'render ..., action: $X
'
- pattern: 'render $X, ...
'
- focus-metavariable: $X
pattern-sanitizers:
- patterns:
- pattern: $MAP[...]
- metavariable-pattern:
metavariable: $MAP
patterns:
- pattern-not-regex: params
- pattern: File.basename(...)
message: "The application dynamically constructs file or path information with user\
\ input when calling the `render` function. This can allow end\nusers to request\
\ arbitrary local files which may result in leaking\nsensitive information persisted\
\ on disk. Where possible, avoid letting\nusers specify template paths for `render`.\
\ If you must allow user input,\nuse an allow-list of known templates or normalize\
\ the user-supplied value\nwith `File.basename(...)`.\n\nTo mitigate this vulnerability,\
\ follow these steps:\n- Avoid direct user input: If possible, do not use user\
\ input \nto determine file paths. Use a mapping of user input to server-side\
\ \ndefined file paths instead.\n- Use `File.basename`: If user input must be\
\ used to specify a file, \nensure that the input is normalized using `File.basename`\
\ to extract \nthe filename without any directory path. This prevents directory\
\ \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted\
\ files or \ndirectories and check user input against this list before processing.\n\
\nSecure Code Example:\n```\nclass PagesController < ApplicationController\n \
\ # Allowlist\n def show\n valid_pages = ['home', 'about_us', 'contact']\n\
\ if valid_pages.include?(params[:page])\n render params[:page]\n else\n\
\ render 'not_found'\n end\n end\n\n # Sanitizing User Input\n def\
\ show\n # Sanitize the user input to extract just the file name\n page\
\ = File.basename(params[:page])\n # Optionally, further validate the sanitized\
\ input against an allow-list or other criteria\n render page\n end\nend\n\
```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-22
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
references:
- https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-render-local-file-include.yaml
category: security
security-severity: MEDIUM
technology:
- rails
- id: ruby_file_rule-CheckSendFile
mode: taint
pattern-sources:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
pattern-sinks:
- patterns:
- pattern: 'send_file ...
'
message: "The application dynamically constructs file or path information with user\
\ input when calling\nthe `send_file` method in Ruby. This practice can lead to\
\ a serious \nsecurity vulnerability known as Local File Inclusion (LFI), allowing\
\ \nattackers to read arbitrary files on the server. \nLFI vulnerabilities can\
\ lead to the exposure of sensitive information, \nsuch as configuration files,\
\ source code, or even data files, \nwhich could be exploited to gain further\
\ access or to mount more \nsevere attacks.\n\nTo mitigate this vulnerability,\
\ follow these steps:\n- Avoid direct user input: If possible, do not use user\
\ input \nto determine file paths. Use a mapping of user input to server-side\
\ \ndefined file paths instead.\n- Use `File.basename`: If user input must be\
\ used to specify a file, \nensure that the input is normalized using `File.basename`\
\ to extract \nthe filename without any directory path. This prevents directory\
\ \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted\
\ files or \ndirectories and check user input against this list before processing.\n\
\nSecure Code Example:\n```\ndef download\n filename = params[:filename]\n filepath\
\ = \"path/to/secure/directory/#{File.basename(filename)}\"\n\n # Optionally,\
\ further validate the resolved filepath against a whitelist\n\n if File.exist?(filepath)\
\ && !File.directory?(filepath)\n send_file filepath, x_sendfile: true\n else\n\
\ render plain: \"File not found\", status: :not_found\n end\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-73
shortDescription: External control of file name or path
references:
- https://owasp.org/www-community/attacks/Path_Traversal
- https://owasp.org/Top10/A01_2021-Broken_Access_Control/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-send-file.yaml
category: security
security-severity: MEDIUM
technology:
- ruby
- rails
- id: ruby_file_rule-AvoidTaintedFileAccess
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
pattern-sinks:
- patterns:
- pattern-either:
- pattern: Dir.$X(...)
- pattern: File.$X(...)
- pattern: IO.$X(...)
- pattern: Kernel.$X(...)
- pattern: PStore.$X(...)
- pattern: Pathname.$X(...)
- metavariable-pattern:
metavariable: $X
patterns:
- pattern-either:
- pattern: chdir
- pattern: chroot
- pattern: delete
- pattern: entries
- pattern: foreach
- pattern: glob
- pattern: install
- pattern: lchmod
- pattern: lchown
- pattern: link
- pattern: load
- pattern: load_file
- pattern: makedirs
- pattern: move
- pattern: new
- pattern: open
- pattern: read
- pattern: readlines
- pattern: rename
- pattern: rmdir
- pattern: safe_unlink
- pattern: symlink
- pattern: syscopy
- pattern: sysopen
- pattern: truncate
- pattern: unlink
message: "The application dynamically constructs file or path information with user\
\ input. When an application uses data from \nuntrusted sources (like `params`,\
\ `cookies`, or `request.env`) to perform \nactions on the file system, it opens\
\ up potential vulnerabilities. \nA malicious actor could exploit this to access,\
\ modify, or delete \nfiles they shouldn't have access to, leading to information\
\ disclosure, \ndata loss, or server compromise. This type of vulnerability is\
\ often \nreferred to as a File Inclusion vulnerability or Path Traversal attack,\
\ \ndepending on the nature of the exploit.\n\nTo mitigate these risks, follow\
\ these best practices:\n- Validate and sanitize input: Ensure all user inputs\
\ are strictly \nvalidated and sanitized to prevent path traversal characters\
\ (like `../`) \nor other malicious patterns. Only allow filenames or paths that\
\ match \nspecific, safe patterns.\n- Use secure libraries: Utilize libraries\
\ or frameworks that abstract \nfile access in a secure manner, automatically\
\ handling the risks \nassociated with raw user input.\n- Least privilege principle:\
\ Run your application with the minimum \nnecessary file system permissions. Restrict\
\ the application's access \nto only those directories and files it absolutely\
\ needs.\n- Directory whitelisting: Maintain an allow list of permitted directories\
\ \nfor file operations, rejecting any requests for paths outside of these \n\
directories.\n\nSecure Code Example:\n```\ndef safe_file_read(filename)\n # Define\
\ a list of allowed files or use regex to validate the filename format\n allowed_files\
\ = ['allowed_file.txt', 'another_safe_file.txt']\n \n if allowed_files.include?(filename)\n\
\ file_path = Rails.root.join('safe_directory', filename)\n content = File.read(file_path)\n\
\ return content\n else\n raise \"Access to the requested file is not allowed.\"\
\n end\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-22
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-file-access.yaml
category: security
security-severity: MEDIUM
technology:
- rails
- id: ruby_mass_assignment_rule-UnprotectedMassAssign
patterns:
- pattern-either:
- pattern: '$MOD.new(params[$CODE])
'
- pattern: '$MOD.new(..., params[$CODE], :without_protection => true, ...)
'
- pattern-not-inside: 'attr_accessible $VAR
...
$MOD.new(params[$CODE])
'
message: "Checks for calls to `without_protection` during mass assignment (which\
\ \nallows record creation from hash values). This can lead to users bypassing\
\ \npermissions protections. Using `:without_protection => true` makes your \n\
application vulnerable to attackers who may craft malicious requests to \nmodify\
\ sensitive attributes, leading to unauthorized access or data \nmanipulation.\
\ For Rails 4 and higher, mass protection is on by default.\n\nTo mitigate this\
\ issue, don't use :without_protection => true. Instead, \nconfigure attr_accessible\
\ to control attribute access.\n\nSecure Code Example:\n```\nclass User < ActiveRecord::Base\n\
\ # Only name and email can be updated via mass assignment\n attr_accessible\
\ :name, :email\n\n # admin and account_id are not listed here, so they cannot\
\ be mass-assigned\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
shortDescription: Improperly controlled modification of dynamically-determined
object attributes
cwe: CWE-915
owasp:
- A6:2017-Security Misconfiguration
- A08:2021-Software and Data Integrity Failures
security-severity: MEDIUM
technology:
- ruby
- rails
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/unprotected-mass-assign.yaml
- id: ruby_mass_assignment_rule-ModelAttrAccessible
pattern-either:
- pattern: '....permit(..., :admin, ...)
'
- pattern: '....permit(..., :role, ...)
'
- pattern: '....permit(..., :banned, ...)
'
- pattern: '....permit(..., :account_id, ...)
'
- pattern: 'attr_accessible ..., :admin, ...
'
- pattern: 'attr_accessible ..., :role, ...
'
- pattern: 'attr_accessible ..., :banned, ...
'
- pattern: 'attr_accessible ..., :account_id, ...
'
- pattern: 'params.permit!
'
message: "The application was found permitting attributes which could lead to mass\
\ assignment\nvulnerabilities. Permitting attributes such as `admin`, `role`,\
\ `banned` etc, \nwithout proper authorization checks can lead to security issues\
\ like unauthorized \naccess or privilege escalation.\n\nRemediation Strategy\n\
- Explicitly permit attributes: Carefully review which attributes are \npermissible\
\ and avoid including sensitive ones in the list.\n- Role-based permissions: Implement\
\ checks that allow only authorized \nusers (e.g., administrators) to modify sensitive\
\ attributes.\n- Avoid using `params.permit!`: Use specific permit statements\
\ instead of \npermitting all parameters to ensure only expected attributes are\
\ allowed \nfor mass assignment.\n\nSecure Code Example:\n```\n# Secure: Conditionally\
\ permit sensitive attributes based on user role\ndef user_params\npermitted =\
\ params.require(:user).permit(:name, :email)\npermitted[:role] = params[:user][:role]\
\ if current_user.admin? && params[:user][:role].present?\npermitted\nend\n\n\
def user_params2\n permitted_attributes = [:username, :email]\n # Only allow\
\ 'admin' attribute to be updated by users with admin role\n permitted_attributes\
\ << :admin if current_user.admin?\n params.require(:user).permit(*permitted_attributes)\n\
end\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
shortDescription: Improperly controlled modification of dynamically-determined
object attributes
cwe: CWE-915
owasp:
- A6:2017-Security Misconfiguration
- A08:2021-Software and Data Integrity Failures
security-severity: MEDIUM
technology:
- ruby
- rails
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/model-attr-accessible.yaml
- id: ruby_xss_rule-ManualTemplateCreation
pattern: ERB.new(...)
message: "The application was identified manually creating ERB templates. Manual\
\ creation of templates\nmay expose your application to server-side template injection\
\ (SSTI) or\ncross-site scripting (XSS) attacks if user input is used to create\
\ the\ntemplate. Instead, create a '.erb' template file and use 'render'.\n\n\
Secure Code Example:\n```\n# Controller: messages_controller.rb\nclass MessagesController\
\ < ApplicationController\n def show\n # Safely assign user input to an instance\
\ variable\n @message_content = sanitize(params[:user_content])\n \n \
\ # Render the static .erb template\n render 'messages/show'\n end\nend\n\n\
<!-- Static ERB Template Example - app/views/messages/show.html.erb -->\n<div>\n\
\ Message: <%= @message_content %>\n</div>\n```\n"
languages:
- ruby
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
technology:
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/manual-template-creation.yaml
- id: ruby_xss_rule-AvoidLinkTo
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
- pattern-either:
- pattern: $MODEL.url(...)
- pattern: $MODEL.uri(...)
- pattern: $MODEL.link(...)
- pattern: $MODEL.page(...)
- pattern: $MODEL.site(...)
pattern-sinks:
- pattern: link_to(...)
pattern-sanitizers:
- patterns:
- pattern: '"...#{...}..."
'
- pattern-not: '"#{...}..."
'
message: "This code includes user input in `link_to`. In Rails, the body of \n`link_to`\
\ is not escaped. This means that user input which reaches the \nbody will be\
\ executed when the HTML is rendered. Even in other versions, \nvalues starting\
\ with `javascript:` or `data:` are not escaped. \n\nMitigation Strategy:\nAlways\
\ sanitize user input used within `link_to` method calls. For versions of \nRails\
\ where `link_to` does not automatically escape the body, or when dealing \nwith\
\ schemes that are not escaped (`javascript:`, `data:`), manually escape or \n\
validate the input against a list of safe values. Consider using the `sanitize`\
\ \nhelper method or other Rails sanitization helpers to clean user input before\
\ \nrendering.\n\nSecure Code Example:\n```\nuser_input = params[:user_link_text]\n\
\n# This example uses the `sanitize` helper to ensure any HTML tags or JavaScript\
\ in the user input are escaped\nsafe_link_text = sanitize(user_input)\n\n# Use\
\ the sanitized text as the body of the `link_to` method\n<%= link_to safe_link_text,\
\ some_safe_path %>\n```\n"
languages:
- ruby
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
technology:
- rails
references:
- https://brakemanscanner.org/docs/warning_types/link_to/
- https://brakemanscanner.org/docs/warning_types/link_to_href/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-link-to.yaml
- id: ruby_xss_rule-AvoidRenderInline
pattern: 'render inline: ...'
message: "The application was found calling `render inline: ...` which renders an\
\ entire ERB template inline and is potentially dangerous.\nIf user supplied input\
\ is used, the application can be exploited by malicious \nactors via server-side\
\ template injection (SSTI) or cross-site scripting (XSS) attacks.\nInstead, consider\
\ using a partial or another safe rendering method.\n\nSecure Code Example:\n\
```\n# In your controller or view\nuser_input = params[:user_input]\nrender partial:\
\ 'users/user_input', locals: { user_input: user_input }\n\n# erb file\n<!-- app/views/users/_user_input.html.erb\
\ -->\n<!-- Display user input safely -->\n<div>\n <%= sanitize(user_input) %>\n\
</div>\n```\n"
languages:
- ruby
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
technology:
- rails
references:
- https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-inline.yaml
- id: ruby_xss_rule-AvoidRenderText
pattern: 'render text: ...'
fix-regex:
regex: 'text:'
replacement: 'plain:'
message: "The application was found calling `render text: ...` which actually sets\
\ the \ncontent-type to 'text/html'. If external data can reach here, this exposes\
\ your \napplication to cross-site scripting (XSS) attacks. Instead, use `render\
\ plain: ...` to\nrender non-HTML text.\n"
languages:
- ruby
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
technology:
- rails
references:
- https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-text.yaml
- id: ruby_regex_rule-CheckValidationRegex
mode: search
patterns:
- pattern-either:
- pattern: 'validates ..., :format => <... $V ...>,...
'
- pattern: 'validates_format_of ..., :with => <... $V ...>,...
'
- metavariable-regex:
metavariable: $V
regex: /(.{2}(?<!\\A)[^\/]+|[^\/]+(?<!\\[Zz]))\/
message: "An incorrectly-bounded regex was passed to `validates_format_of` \nor\
\ `validate ... format => ...`.\n\nRuby regex behavior is multiline by default\
\ and lines should be terminated \nby `\\A` for beginning of line and `\\Z` for\
\ end of line, respectively.\n\nSecure Code Example:\n```\nclass User < ApplicationRecord\n\
\ # Securely anchored from start to end of the string\n validates :username,\
\ format: { with: /\\A(?=.*[a-zA-Z])[a-zA-Z0-9]+\\z/ }\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
cwe: CWE-185
shortDescription: Incorrect regular expression
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
technology:
- ruby
- rails
references:
- https://brakemanscanner.org/docs/warning_types/format_validation/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-validation-regex.yaml
- id: ruby_regex_rule-CheckRegexDOS
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
- patterns:
- pattern: $Y
- pattern-either:
- pattern-inside: '$RECORD.read_attribute($Y)
'
- pattern-inside: '$RECORD[$Y]
'
- metavariable-regex:
metavariable: $RECORD
regex: '[A-Z][a-z]+'
pattern-sinks:
- patterns:
- pattern-either:
- patterns:
- pattern: $Y
- pattern-inside: '/...#{...}.../
'
- patterns:
- pattern: $Y
- pattern-inside: 'Regexp.new(...)
'
message: "The application was found constructing a regular expression with user-controllable\n\
input. This may result in excessive resource consumption \nwhen applied to certain\
\ inputs, or when the user is allowed to control \nthe match target.\n\nTo mitigate\
\ the issue, avoid allowing users to specify regular expressions \nprocessed by\
\ the server. If you must support user-controllable input in a \nregular expression,\
\ use an allow-list to restrict the expressions users \nmay supply to limit catastrophic\
\ backtracking.\n\nSecure Code Example:\n```\n# Define an allow-list of safe,\
\ predefined patterns\nALLOWED_PATTERNS = {\n 'digits_only' => /^\\d+$/,\n 'letters_only'\
\ => /^[a-zA-Z]+$/,\n 'email_format' => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\
.[a-zA-Z]{2,}$/\n}\nuser_pattern_key = params[:pattern_key]\ntarget_data = params[:data]\n\
\nif ALLOWED_PATTERNS.key?(user_pattern_key)\n # Fetch the safe pattern from\
\ the allow-list\n safe_pattern = ALLOWED_PATTERNS[user_pattern_key]\n \n #\
\ Apply the regular expression safely\n if target_data.match(safe_pattern)\n\
\ # Do something\n else\n # Do something\n end\nelse\n # Handle case\
\ where the pattern is not allowed\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
cwe: CWE-1333
shortDescription: Inefficient regular expression complexity
owasp:
- A6:2017-Security Misconfiguration
- A04:2021-Insecure Design
security-severity: MEDIUM
technology:
- ruby
- rails
references:
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-regex-dos.yaml
- id: ruby_exceptions_rule-DetailedExceptions
patterns:
- pattern-either:
- patterns:
- pattern: 'config.consider_all_requests_local = true
'
- patterns:
- pattern-inside: "class $CONTROLLER < ApplicationController\n ...\nend\n"
- pattern: "def show_detailed_exceptions? (...)\n ...\nreturn $RETURN\nend\n"
- metavariable-pattern:
metavariable: $RETURN
patterns:
- pattern-not: 'false
'
message: "The `consider_all_requests_local` setting was found set to true, which\
\ enables detailed exception reports. This setting, \nwhile useful during development\
\ for debugging purposes, can \ninadvertently expose sensitive system or application\
\ information \nto end users when enabled in production environments. Such \n\
information exposure could potentially aid attackers in crafting \nfurther attacks\
\ against the system.\n\nIt is advisable to disable detailed exception reporting\
\ in production \nenvironments to prevent the leakage of sensitive information.\
\ \n\nSecure Configuration Example:\n```\n# config/environments/production.rb\n\
Rails.application.config.consider_all_requests_local = false\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A05:2021-Security Misconfiguration
shortDescription: Generation of error message containing sensitive information
cwe: CWE-209
category: security
security-severity: MEDIUM
technology:
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/detailed-exceptions.yaml
- id: ruby_csrf_rule-MissingCSRFProtection
patterns:
- pattern: "class $CONTROLLER < ActionController::Base\n ...\nend\n"
- pattern-not: "class $CONTROLLER < ActionController::Base\n ...\n protect_from_forgery\n\
end\n"
message: "Detected controller which does not enable cross-site request forgery\n\
protections using `protect_from_forgery`. When a Rails application does \nnot\
\ use `protect_from_forgery` in its controllers, it is vulnerable to \nCSRF attacks.\
\ This vulnerability can allow attackers to submit unauthorized \nrequests on\
\ behalf of authenticated users, potentially leading to \nunauthorized actions\
\ being performed. \nTo mitigate this risk, Rails offers the `protect_from_forgery`\
\ method, \nwhich integrates CSRF token verification in every form submitted to\
\ \nyour application, ensuring that requests are legitimate. \nAdd `protect_from_forgery\
\ with: :exception` to your controller class. \nThe `with: :exception` option\
\ configures Rails to raise an exception \nif a CSRF token cannot be verified,\
\ providing an additional layer of security. \nThis approach ensures that unverified\
\ requests do not proceed silently, \nallowing for appropriate error handling\
\ and response measures.\n\nSecure Code Example:\n```\nclass YourController <\
\ ApplicationController\n protect_from_forgery with: :exception\n # Your controller\
\ actions here\nend\n```\nFor more information on CSRF, see OWASP guide:\nhttps://owasp.org/www-community/attacks/csrf\n"
languages:
- ruby
metadata:
shortDescription: Cross-site request forgery (CSRF)
category: security
cwe: CWE-352
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
technology:
- ruby
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/missing-csrf-protection.yaml
- https://owasp.org/Top10/A01_2021-Broken_Access_Control
severity: WARNING
- id: ruby_injection_rule-BadSend
pattern-either:
- pattern: '$PARAM = params[...]
...
$RES = $MOD.send($PARAM.$FUNC)
'
- pattern: '$PARAM = params[...]
...
$RES = $MOD.try($PARAM.$FUNC)
'
- pattern: '$PARAM = params[...]
...
$RES = $MOD.__send__($PARAM.$FUNC)
'
- pattern: '$PARAM = params[...]
...
$RES = $MOD.public_send($PARAM.$FUNC)
'
message: "The application was found calling dynamic method invocations in Ruby.\
\ \nIn particular one of the methods of: `Object#send`, `Object#try`, `Object#__send__`,\
\ \nor `Object#public_send`. These methods are powerful Ruby features that allow\
\ \ncalling another method on an object \nby name, where the method's name is\
\ passed as a string or symbol. \nHowever, when combined with untrusted input,\
\ such as parameters from \nweb requests, they can lead to severe security vulnerabilities,\
\ including \narbitrary method execution and potentially arbitrary code execution.\n\
\nTo mitigate these risks, it's crucial to validate and sanitize any user \ninput\
\ that might determine which methods are invoked. Moreover, consider \nusing safer\
\ alternatives to direct method invocation based on user input, \nsuch as explicitly\
\ whitelisting allowed methods or using conditional logic \nto determine method\
\ calls.\n\nSecure Code Example:\n```\n# Secure method invocation with validation\
\ and allow lists\nmethod_name = params[:method].to_sym\nallowed_methods = [:allowed_method_1,\
\ :allowed_method_2, :safe_method]\n\nif allowed_methods.include?(method_name)\n\
\ result = object.public_send(method_name)\nelse\n raise \"Unauthorized method\
\ call\"\nend\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
technology:
- ruby
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-send.yaml
- https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html
- id: ruby_injection_rule-DangerousExec
mode: taint
pattern-sources:
- patterns:
- pattern: "def $F(...,$ARG,...)\n ...\nend\n"
- focus-metavariable: $ARG
- pattern: params
- pattern: cookies
pattern-sinks:
- patterns:
- pattern: '$EXEC(...)
'
- pattern-not: '$EXEC("...","...","...",...)
'
- pattern-not: '$EXEC(["...","...","...",...],...)
'
- pattern-not: '$EXEC({...},"...","...","...",...)
'
- pattern-not: '$EXEC({...},["...","...","...",...],...)
'
- metavariable-regex:
metavariable: $EXEC
regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$
message: "OS command injection is a critical vulnerability that can lead to a full\
\ system\ncompromise as it may allow an adversary to pass in arbitrary commands\
\ or arguments\nto be executed.\n\nUser input should never be used in constructing\
\ commands or command arguments\nto functions which execute OS commands. This\
\ includes filenames supplied by\nuser uploads or downloads.\n\nTo mitigate this\
\ vulnerability, follow these best practices:\n- Validate input: Ensure that all\
\ user inputs are validated against a \nstrict pattern that only allows safe characters\
\ for the context. Reject \nany input that does not meet these criteria.\n- Sanitize\
\ input: When validation is not feasible, sanitize the input \nby escaping or\
\ removing potentially dangerous characters.\n- Use secure methods: Prefer using\
\ secure methods or libraries designed \nto execute system commands with parameters,\
\ which automatically handle \nproper escaping of user inputs, such as `Open3.capture3`\
\ in Ruby.\n- Least privilege: Run your application with the least privileges\
\ \nnecessary, limiting what an attacker can do if they manage to execute a \n\
command.\n\nSecure Code Example:\nInstead of directly interpolating user input\
\ into system commands, validate \nuser input against an allowlist, then use parameterized\
\ execution or safer \nAPIs like Open3:\n```\nrequire 'open3'\n\nuser_input =\
\ params[:user_input]\n# Define an allow list of permitted arguments\nallowed_arguments\
\ = ['allowed_argument1', 'allowed_argument2', 'allowed_argument3']\n\n# Validate\
\ user_input against the list\nif allowed_arguments.include?(user_input)\n #\
\ Using Open3 to safely execute system commands with allowed arguments\n stdout,\
\ stderr, status = Open3.capture3('grep', user_input, 'my_file.txt')\n if status.success?\n\
\ puts stdout\n else\n warn \"Error: #{stderr}\"\n end\nelse\n warn \"\
Error: Unpermitted argument.\"\nend\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
technology:
- ruby
- rails
references:
- https://guides.rubyonrails.org/security.html#command-line-injection
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/dangerous-exec.yaml
- id: ruby_injection_rule-AvoidTaintedShellCall
mode: taint
pattern-sources:
- pattern-either:
- pattern: params[...]
- pattern: cookies
- pattern: request.env
pattern-sinks:
- patterns:
- pattern-either:
- patterns:
- pattern: Kernel.$X(...)
- patterns:
- pattern-either:
- pattern: Shell.$X(...)
- patterns:
- pattern-inside: '$SHELL = Shell.$ANY(...)
...
$SHELL.$X(...)
'
- pattern: $SHELL.$X(...)
- metavariable-pattern:
metavariable: $X
patterns:
- pattern-either:
- pattern: cat
- pattern: chdir
- pattern: chroot
- pattern: delete
- pattern: entries
- pattern: exec
- pattern: foreach
- pattern: glob
- pattern: install
- pattern: lchmod
- pattern: lchown
- pattern: link
- pattern: load
- pattern: load_file
- pattern: makedirs
- pattern: move
- pattern: new
- pattern: open
- pattern: read
- pattern: readlines
- pattern: rename
- pattern: rmdir
- pattern: safe_unlink
- pattern: symlink
- pattern: syscopy
- pattern: sysopen
- pattern: system
- pattern: truncate
- pattern: unlink
message: "User input should never be used in constructing commands or command arguments\n\
to functions which execute OS related functionality. Using external \ninput without\
\ validation in functions like `Kernel.system`, `exec`, or any \noperations that\
\ interact with the shell or file system (`cat`, `delete` \netc.) poses a severe\
\ security risk. These patterns can lead to command \ninjection vulnerabilities,\
\ where an attacker could execute arbitrary \ncommands on the system the application\
\ is hosted on, leading to data \nbreaches, unauthorized access, or worse.\n\n\
To prevent command injection vulnerabilities, validate and sanitize all \nuser\
\ input before using it in any system or shell operation. Additionally, \nconsider\
\ using safer alternatives for executing system commands that don't \ndirectly\
\ pass user input to the shell, such as parameterized APIs or \nfunctions that\
\ handle arguments safely.\n\nSecure Code Example:\n```\nuser_filename_key = params[:filename_key]\n\
\nallowed_filenames = {\n 'file1' => 'allowed_file_1.txt',\n 'file2' => 'allowed_file_2.txt',\n\
}\n\n# Validate and select the filename from the lookup table\nif allowed_filenames.has_key?(user_filename_key)\n\
\ safe_filename = allowed_filenames[user_filename_key]\n\n # Use a safer API\
\ to read file content without invoking the shell\n content = File.read(safe_filename)\n\
else\n puts \"Invalid filename.\"\nend\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-78
security-severity: HIGH
technology:
- rails
- ruby
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-shell-call.yaml
- id: ruby_http_rule-AvoidTaintedHTTPRequest
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
pattern-sinks:
- pattern-either:
- patterns:
- pattern: Net::HTTP::$METHOD.new(...)
- metavariable-pattern:
metavariable: $METHOD
patterns:
- pattern-either:
- pattern: Copy
- pattern: Delete
- pattern: Get
- pattern: Head
- pattern: Lock
- pattern: Mkcol
- pattern: Move
- pattern: Options
- pattern: Patch
- pattern: Post
- pattern: Propfind
- pattern: Proppatch
- pattern: Put
- pattern: Trace
- pattern: Unlock
- patterns:
- pattern: Net::HTTP.$X(...)
- metavariable-pattern:
metavariable: $X
patterns:
- pattern-either:
- pattern: get
- pattern: get2
- pattern: head
- pattern: head2
- pattern: options
- pattern: patch
- pattern: post
- pattern: post2
- pattern: post_form
- pattern: put
- pattern: request
- pattern: request_get
- pattern: request_head
- pattern: request_post
- pattern: send_request
- pattern: trace
- pattern: get_print
- pattern: get_response
- pattern: start
message: "The application was found including unvalidated user input into `Net::HTTP`\
\ methods, \nwhich could lead to HTTP Parameter Pollution (HPP) or worse, Server\
\ Side Request Forgery (SSRF).\nSpecifically, it looks for methods like GET, POST,\
\ DELETE, etc., \nbeing called with parameters that could be controlled by an\
\ end-user. \nUsing untrusted input in such a manner without proper validation\
\ and \nsanitization can lead to a variety of security vulnerabilities, including\
\ \nSSRF, injection attacks, unintended data leaks, and unauthorized actions \n\
being performed on behalf of the attacker.\n\nEnsure all user-controlled input\
\ is validated against a strict set of rules \n(e.g., expected data types, patterns,\
\ and lengths) and sanitized to remove \nor encode potentially harmful characters\
\ before being used in HTTP requests. \nAdditionally, consider using higher-level\
\ abstractions or frameworks that \nautomatically handle some of these concerns.\n\
\nSecure Code Example:\n```\nrequire 'uri'\n\n# Validate and sanitize the user\
\ input before using it in the HTTP request\nbegin\n user_input = params[:url]\n\
\ uri = URI.parse(user_input)\n\n # Ensure the URI is HTTP/HTTPS and refers\
\ to a trusted domain\n if uri.scheme.match?(/\\Ahttps?\\z/) && uri.host == 'www.abc.com'\n\
\ response = Net::HTTP.get(uri)\n else\n raise \"Invalid URL\"\n end\n\
rescue URI::InvalidURIError\n puts \"Provided URL is not valid\"\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
shortDescription: Server side request forgery (SSRF)
cwe: CWE-918
owasp:
- A1:2017-Injection
- A10:2021-Server-Side Request Forgery
security-severity: MEDIUM
technology:
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-http-request.yaml
- id: ruby_http_rule-CheckHTTPVerbConfusion
mode: search
patterns:
- pattern: "if request.get?\n ...\nelse\n ...\nend\n"
- pattern-not-inside: "if ...\nelsif ...\n ...\nend\n"
message: "Found an improperly constructed control flow block with `request.get?`.\
\ \nRails will route HEAD requests as GET requests but they will fail the \n`request.get?`\
\ check, potentially causing unexpected behavior unless an \n`elsif` condition\
\ is used.\n\nSecure Code Example:\n```\nif request.get?\n # Handle GET request\
\ logic here\nelsif request.head?\n # Handle HEAD request logic here\nelse\n\
\ # Handle others if needed\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
category: security
shortDescription: Improper check for unusual or exceptional conditions
cwe: CWE-754
owasp:
- A6:2017-Security Misconfiguration
- A04:2021-Insecure Design
security-severity: MEDIUM
technology:
- ruby
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-http-verb-confusion.yaml
- id: ruby_redirect_rule-CheckRedirectTo
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: params
- pattern: cookies
- pattern: request.env
- pattern: url_for(params[...],...,:only_path => false,...)
pattern-sanitizers:
- patterns:
- pattern-either:
- patterns:
- pattern: '$F(...)
'
- metavariable-pattern:
metavariable: $F
patterns:
- pattern-not-regex: (params|url_for|cookies|request.env|permit|redirect_to)
- pattern: 'params.merge! :only_path => true
...
'
- pattern: 'params.slice(...)
...
'
- pattern: 'redirect_to [...]
'
- patterns:
- pattern: '$MODEL. ... .$M(...)
...
'
- metavariable-regex:
metavariable: $MODEL
regex: '[A-Z]\w+'
- metavariable-regex:
metavariable: $M
regex: (all|create|find|find_by|find_by_sql|first|last|new|from|group|having|joins|lock|order|reorder|select|where|take)
- patterns:
- pattern: 'params.$UNSAFE_HASH.merge(...,:only_path => true,...)
...
'
- metavariable-regex:
metavariable: $UNSAFE_HASH
regex: to_unsafe_h(ash)?
- patterns:
- pattern: params.permit(...,$X,...)
- metavariable-pattern:
metavariable: $X
patterns:
- pattern-not-regex: (host|port|(sub)?domain)
pattern-sinks:
- patterns:
- pattern: $X
- pattern-inside: 'redirect_to $X, ...
'
- pattern-not-regex: params\.\w+(?<!permit)\(.*?\)
message: "The application was found handling redirect behavior with user-supplied\
\ input. \nDo not pass `params` to `redirect_to` without the `:only_path => true`\
\ \nhash value. Using `:only_path => true` ensures that the URL is interpreted\
\ \nas a relative path, not allowing redirection to an arbitrary external URL,\
\ \nthus mitigating the risk of open redirects. Alternatively, validate or \n\
sanitize the input to ensure it's safe and intended.\n\nSecure Code Example:\n\
```\n# Secure - Ensuring redirection is only to internal paths\ndef secure_redirect\n\
\ redirect_to params[:redirect_url], only_path: true\nend\n```\n"
languages:
- ruby
severity: INFO
metadata:
shortDescription: URL redirection to untrusted site 'open redirect'
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-601
security-severity: LOW
technology:
- ruby
- rails
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-redirect-to.yaml
- id: ruby_cookie_rule-CookieSerialization
message: "The rule warns of a significant security risk in applications that use\
\ \nRuby's Marshal module for deserializing cookies. Marshal can serialize \n\
and deserialize Ruby objects, which, while powerful, poses a risk if \nmisused.\
\ If an attacker crafts a malicious cookie that is deserialized, \nit could lead\
\ to remote code execution (RCE) on the server due to \nMarshal.load's ability\
\ to execute code in deserialized objects. To mitigate \nthis risk, developers\
\ are advised to switch from Marshal to JSON for cookie \nserialization. JSON\
\ is safer as it cannot execute arbitrary code, reducing \nthe threat of RCE vulnerabilities\
\ from deserialized user data. The hybrid \ncheck is just to warn users to migrate\
\ to :json for best practice.\n\nSecure code example:\n```\n# In Rails, configure\
\ the cookie serializer to :json\n# config/initializers/cookies_serializer.rb\n\
Rails.application.config.action_dispatch.cookies_serializer = :json\n```\n\nAdditionally,\
\ always validate and sanitize user-supplied data as much \nas possible, even\
\ when using JSON, to further secure your application \nagainst various injection\
\ attacks.\n"
languages:
- ruby
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- ruby
security-severity: HIGH
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/cookie-serialization.yaml
- https://robertheaton.com/2013/07/22/how-to-hack-a-rails-app-using-its-secret-token/
severity: ERROR
pattern-either:
- pattern: 'Rails.application.config.action_dispatch.cookies_serializer = :marshal
'
- pattern: Rails.application.config.action_dispatch.cookies_serializer = :hybrid
- id: ruby_cookie_rule-CheckCookieStoreSessionSecurityAttributes
patterns:
- pattern-either:
- patterns:
- pattern: ':$KEY => false
'
- pattern-inside: 'ActionController::Base.session = {...}
'
- pattern: '$MODULE::Application.config.session_store :cookie_store, ..., :$KEY
=> false, ...
'
- pattern: '$CLASS.application.config.session_store :cookie_store, ..., $KEY:
false, ...
'
- metavariable-regex:
metavariable: $KEY
regex: ^(session_)?(http_?only|secure)$
message: "The detected issue pertains to a Rails application where the session \n\
configuration, specifically using cookie_store, has been identified \nwith the\
\ $KEY attribute set to false. This setting is potentially \ninsecure because\
\ it may relate to crucial security attributes such \nas HttpOnly or Secure flags\
\ not being enforced. In the context of \nweb applications, these flags play a\
\ vital role in enhancing session \nsecurity:\n\n- HttpOnly Flag: When enabled,\
\ this flag prevents client-side scripts\nfrom accessing the cookie. This mitigation\
\ is crucial for reducing \nthe risk of cross-site scripting (XSS) attacks, where\
\ an attacker \nmight attempt to steal session cookies.\n- Secure Flag: This flag\
\ ensures that cookies are sent over secure, \nencrypted connections only (HTTPS).\
\ It's a critical security measure \nthat helps prevent cookies from being intercepted\
\ by attackers when \ntransmitted over an unencrypted connection.\n\nTo mitigate\
\ the identified security risk and ensure that your Rails \napplication's session\
\ cookies are securely configured. \n\nSecure Code Example:\n```\n# config/initializers/session_store.rb\n\
Rails.application.config.session_store :cookie_store, key: '_your_app_session',\n\
\ httponly: true,\n \
\ secure: Rails.env.production?\n```\n"
languages:
- ruby
severity: INFO
metadata:
category: security
shortDescription: Sensitive cookie without 'HttpOnly' and 'Secure' flags
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-1004
technology:
- ruby
- rails
security-severity: LOW
references:
- https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-cookie-store-session-security-attributes.yaml
- id: ruby_eval_rule-NoEval
message: "The `eval` method in Ruby executes a string argument as Ruby code. When\
\ \n`eval` is used with input that can be controlled or manipulated by an \nexternal\
\ user, it can allow arbitrary code execution. This \nmeans an attacker could\
\ potentially execute malicious code on the server, \nleading to unauthorized\
\ access, data leakage, or server compromise.\n\nRemediation Steps:\n- Validate\
\ and sanitize input: If there's an absolute necessity to use \n`eval`, ensure\
\ that any user input is rigorously validated and sanitized \nto remove potentially\
\ harmful code. However, this is generally not \nrecommended due to the difficulty\
\ of securely sanitizing code.\n- Use safer alternatives: Depending on the requirement,\
\ consider using \nsafer alternatives to `eval`, such as `send` for calling methods\
\ dynamically \nor employing DSLs (Domain-Specific Languages) and safe parsing\
\ libraries \ndesigned for specific tasks.\n\nSecure Code Example:\n```\nclass\
\ Calculator\n def add(a, b)\n a + b\n end\nend\n\n# Safer alternative using\
\ send\ncalculator = Calculator.new\nmethod = params[:operation] # Example: 'add'\
\ or 'subtract'\na = params[:a].to_i\nb = params[:b].to_i\n\nif calculator.respond_to?(method)\n\
\ result = calculator.send(method, a, b)\nelse\n puts \"Invalid operation\"\n\
end\n```\n\nIn this example, `send` is used to dynamically call a method on the\
\ \nCalculator object based on user input. This approach is safer than \neval\
\ because it strictly limits the operations to those defined in \nthe class, preventing\
\ arbitrary code execution.\n"
severity: ERROR
metadata:
cwe: CWE-95
shortDescription: Improper neutralization of directives in dynamically evaluated
code ('Eval Injection')
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
references:
- https://owasp.org/Top10/A03_2021-Injection
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-eval.yaml
technology:
- rails
languages:
- ruby
mode: taint
pattern-sources:
- pattern-either:
- pattern: params
- pattern: cookies
- patterns:
- pattern: 'RubyVM::InstructionSequence.compile(...)
'
- pattern-not: 'RubyVM::InstructionSequence.compile("...")
'
pattern-sinks:
- patterns:
- pattern-either:
- pattern: $X.eval
- pattern: $X.class_eval
- pattern: $X.instance_eval
- pattern: $X.module_eval
- pattern: $X.eval(...)
- pattern: $X.class_eval(...)
- pattern: $X.instance_eval(...)
- pattern: $X.module_eval(...)
- pattern: eval(...)
- pattern: class_eval(...)
- pattern: module_eval(...)
- pattern: instance_eval(...)
- pattern-not: $M("...",...)
- id: ruby_find_rule-CheckUnscopedFind
mode: taint
pattern-sources:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
pattern-sinks:
- patterns:
- pattern-either:
- pattern: $MODEL.find(...)
- pattern: $MODEL.find_by_id(...)
- pattern: $MODEL.find_by_id!(...)
- metavariable-regex:
metavariable: $MODEL
regex: '[A-Z]\S+'
message: "The application was found calling the `find(...)` method with user-controlled\
\ input. If the \nActiveRecord model being searched against is sensitive, this\
\ may lead to \nInsecure Direct Object Reference (IDOR) behavior and allow users\
\ to read \narbitrary records. This could lead to data breaches, including the\
\ \nexposure of personal information, account takeovers, and other security \n\
issues.\n\nTo mitigate this risk, it's essential to scope queries to the current\
\ \nuser or another appropriate scope that ensures users can only access \ndata\
\ they are authorized to see. This is done by using ActiveRecord \nassociations\
\ and scopes to limit the records that can be retrieved. \n\nSecure Code Example:\n\
```\n# Secure way to scope the find to the current user's accounts\ndef show\n\
\ @account = current_user.accounts.find(params[:id])\nend\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-639
shortDescription: Authorization bypass through user-controlled key
references:
- https://brakemanscanner.org/docs/warning_types/unscoped_find/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unscoped-find.yaml
category: security
security-severity: MEDIUM
technology:
- ruby
- rails
- id: ruby_filter_rule-CheckBeforeFilter
mode: search
patterns:
- pattern-either:
- pattern: 'skip_filter ..., :except => $ARGS
'
- pattern: 'skip_before_filter ..., :except => $ARGS
'
message: "The application was found disabling controller checks by setting `skip_filter`\
\ \nor `skip_before_filter` with an `:except` option. This approach can \ninadvertently\
\ open up parts of your application to unauthorized access \nbecause it relies\
\ on a blocklist approach, where only specified actions \nare protected. \n\n\
A safer method of providing this functionality involves specifying \nexactly which\
\ controller actions should have checks applied using an \n`:only` option, effectively\
\ creating an allowlist. This method ensures \nthat only specified actions are\
\ affected, and any new actions added to \nthe controller will have the filters\
\ applied by default, adhering to the \nprinciple of secure by default.\n\nSecure\
\ Code Example:\n```\nclass UsersController < ApplicationController\n # Apply\
\ the filter only to these actions, making it clear and secure by default\n skip_before_action\
\ :authenticate_user!, only: [:new, :create]\nend\n```\n\nIn the secure example,\
\ `:authenticate_user!` filter is explicitly skipped \nonly for the `:new` and\
\ `:create actions`. This means any new action added \nto the UsersController\
\ in the future will have the `authenticate_user!` \nfilter applied by default,\
\ ensuring that new parts of the application \nare secure from the start. \n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-749
shortDescription: Exposed dangerous method or function
references:
- https://owasp.org/Top10/A01_2021-Broken_Access_Control/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-before-filter.yaml
category: security
security-severity: LOW
technology:
- ruby
- rails
- id: ruby_error_rule-DivideByZero
mode: taint
pattern-sources:
- patterns:
- pattern: $VAR
- metavariable-regex:
metavariable: $VAR
regex: ^\d*(?!\.)$
pattern-sinks:
- patterns:
- pattern-inside: $NUMBER / 0
- pattern: $NUMBER
message: "A ZeroDivisionError exception has been detected, this occurs when an arithmetic\
\ operation attempts to \ndivide a number by zero. This can happen in various\
\ contexts, such as \nprocessing user inputs, performing calculations with variables,\
\ or \nworking with data from external sources. Such errors not only disrupt \n\
the normal flow of the application but also can be exploited in certain \nscenarios\
\ to cause harm (eg. possible dos) or extract information based \non the application's\
\ response to the error.\n\nTo prevent ZeroDivisionError exceptions and ensure\
\ application robustness:\n- Error handling: Implement error handling around division\
\ operations to \ncatch and manage ZeroDivisionError gracefully.\n- Validation:\
\ Always validate inputs that are used in division operations \nto ensure they\
\ are not zero or unexpected values.\n"
languages:
- ruby
severity: WARNING
metadata:
shortDescription: Divide a number by zero
category: security
cwe: CWE-369
owasp:
- A6:2017-Security Misconfiguration
- A04:2021-Insecure Design
security-severity: LOW
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/divide-by-zero.yaml
technology:
- ruby
- id: ruby_routes_rule-AvoidDefaultRoutes
patterns:
- pattern-either:
- pattern: map.connect ":controller/:action/:id"
- pattern: match ':controller(/:action(/:id(.:format)))'
paths:
include:
- '*routes.rb'
message: "Default routes are enabled in this routes file. This means any public\
\ method on a\ncontroller can be called as an action. It is easy to accidentally\
\ expose\nmethods. Instead, remove the offending line and explicitly include all\n\
routes that are intended for external users to follow.\n\nSecure Code Example:\n\
```\n# In routes.rb\nRails.application.routes.draw do\n get 'posts' => 'posts#index',\
\ as: :posts\n get 'posts/:id' => 'posts#show', as: :post\n post 'posts' =>\
\ 'posts#create'\n\n # Other CRUD actions for posts can be defined similarly\n\
end\n```\n"
languages:
- ruby
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-276
shortDescription: Incorrect Default Permissions
security-severity: MEDIUM
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-default-routes.yaml
category: security
technology:
- rails
- id: ruby_reflection_rule-CheckUnsafeReflectionMethods
mode: taint
pattern-sources:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
pattern-sinks:
- patterns:
- pattern: $X
- pattern-either:
- pattern-inside: '$X. ... .to_proc
'
- patterns:
- pattern-inside: '$Y.method($Z)
'
- focus-metavariable: $Z
- patterns:
- pattern-inside: '$Y.tap($Z)
'
- focus-metavariable: $Z
- patterns:
- pattern-inside: '$Y.tap{ |$ANY| $Z }
'
- focus-metavariable: $Z
message: "The application was found calling a reflection method with user-controllable\n\
input. This practice can lead to unauthorized alteration of program behavior,\
\ \nincluding the potential execution of arbitrary code. Reflection methods \n\
allow dynamic execution of code, which is powerful but risky if not properly \n\
sanitized, as it could enable attackers to execute unintended methods or \nblocks.\n\
\nRemediation:\n- Validate and sanitize input: Ensure that any user input is strictly\
\ \nvalidated against a whitelist of allowed values before being passed to \n\
reflection methods. Avoid direct mapping of user input to method names \nor proc\
\ conversions.\n- Limit reflection use: Minimize the use of reflection with user\
\ input. \nPrefer direct method calls or other non-reflective approaches whenever\
\ \npossible.\n- Use safer alternatives: When dynamic behavior is necessary, use\
\ controlled \nmethods like `public_send` with proper input validation to reduce\
\ risk.\n\nSecure Code Example:\n```\n# Assume user input is to invoke a method\
\ on an object\nuser_method = params[:method_name]\n\n# Define an allow list of\
\ permissible methods\nallowed_methods = ['safe_method_1', 'safe_method_2']\n\n\
if allowed_methods.include?(user_method)\n # Using public_send for controlled\
\ method invocation\n result = my_object.public_send(user_method)\nelse\n \
\ raise 'Unauthorized method access'\nend\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
technology:
- ruby
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection-methods.yaml
- id: ruby_reflection_rule-CheckUnsafeReflection
mode: taint
pattern-sources:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
pattern-sinks:
- patterns:
- pattern: $X
- pattern-either:
- pattern-inside: '$X.constantize
'
- pattern-inside: '$X. ... .safe_constantize
'
- pattern-inside: 'const_get(...)
'
- pattern-inside: 'qualified_const_get(...)
'
message: "The application was found calling a reflection method with user-controllable\n\
input. Reflection in Ruby allows a program to examine and modify its own \nstructure\
\ and behavior at runtime. When user input is used unsafely \nwith reflection\
\ methods (like `constantize`, `safe_constantize`, `const_get`, \n`qualified_const_get`),\
\ it poses a significant security risk, potentially \nleading to arbitrary code\
\ execution.\n\nTo mitigate these risks:\n- Avoid direct user input in reflection:\
\ Never use user-controllable input \ndirectly with reflection methods.\n- Validate\
\ and sanitize input: If user input must influence program behavior, \nrigorously\
\ validate and sanitize the input against a whitelist of allowed \nvalues.\n-\
\ Use indirect references: Instead of allowing direct specification of class \n\
or method names, map user inputs to a predefined set of allowed actions or \n\
classes.\n- Do not provide user-controllable input to reflection functionality.\
\ \n- Do not call symbol conversion on user-controllable input.\n\nSecure Code\
\ Example:\n```\nclass SafeClassHandler\n ALLOWED_CLASSES = {\n 'user' =>\
\ User,\n 'product' => Product\n }.freeze\n\n def self.handle_class_action(class_key)\n\
\ klass = ALLOWED_CLASSES[class_key]\n raise ArgumentError, \"Invalid class\
\ key\" unless klass\n\n klass.some_method\n end\nend\n\n# Example usage\n\
SafeClassHandler.handle_class_action(params[:class_key])\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
technology:
- ruby
- rails
references:
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection.yaml
- id: ruby_deserialization_rule-BadDeserializationYAML
patterns:
- pattern: 'YAML.$LOAD($...ARGS)
'
- pattern-not: 'YAML.$LOAD(..., safe: true, ...)
'
- pattern-not: 'YAML.$LOAD("...", ...)
'
- pattern-not-inside: '$FILE = File.read("...", ...)
...
YAML.$LOAD(..., $FILE, ...)
'
- pattern-not-inside: '$FILENAME = "..."
...
$FILE = File.read($FILENAME, ...)
...
YAML.$LOAD(..., $FILE, ...)
'
- pattern-not-inside: 'YAML.$LOAD(..., File.read("...", ...), ...)
'
- metavariable-regex:
metavariable: $LOAD
regex: load(?:_stream)?\b|parse_stream
fix: Psych.safe_load($...ARGS)
message: "Unsafe deserialization from YAML. \nYAML is a popular format for configuration\
\ files in Ruby applications \ndue to its readability and simplicity. However,\
\ the `load` method \nprovided by Ruby's YAML module can be dangerous when used\
\ to deserialize \ndata from untrusted sources. The method can instantiate objects\
\ based \non the YAML input, which can lead to remote code execution (RCE) if\
\ the \ninput contains malicious code. \n\nTo mitigate the risk of RCE through\
\ unsafe deserialization practices, \nconsider the following recommendations:\n\
- Prefer JSON for untrusted data: JSON is generally safer for \ndeserializing\
\ untrusted data because, by design, it does not support \nthe execution of arbitrary\
\ code. Ensure that any JSON deserialization \nis performed with caution, validating\
\ and sanitizing the input before \nuse.\n- Use safe YAML loading methods: If\
\ you must use YAML, prefer safe \nloading methods like `safe_load` instead of\
\ `load`. The `safe_load` method \nlimits the objects that can be deserialized,\
\ reducing the risk of \nexecuting arbitrary code.\n- Static YAML files: Loading\
\ YAML from static, trusted files (like \nconfiguration files that are not exposed\
\ to user input) is generally \nsafe. Ensure these files are securely managed\
\ and not modifiable by \nuntrusted sources.\n\nSecure Code Example:\n```\nrequire\
\ 'yaml'\nrequire 'json'\n\n# Safe YAML deserialization\ndef safe_load_yaml(file_path)\n\
\ YAML.safe_load(File.read(file_path), [Date, Time], [], true)\nend\n\n# Example\
\ of safely loading a static YAML file\nconfig_data = safe_load_yaml('config.yml')\n\
puts config_data.inspect\n\n# Safe JSON deserialization\ndef safe_load_json(json_input)\n\
\ # Always validate and sanitize input before deserialization\n JSON.parse(json_input)\n\
end\n\n# Example JSON input\njson_input = '{\"name\": \"Jack Monroe\", \"age\"\
: 30}'\nuser_data = safe_load_json(json_input)\nputs user_data.inspect\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Deserialization of untrusted data
category: security
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
security-severity: HIGH
technology:
- ruby
- yaml
references:
- https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-yaml.yaml
- id: ruby_deserialization_rule-BadDeserializationEnv
mode: taint
pattern-sources:
- pattern-either:
- pattern: request.env
pattern-sinks:
- pattern-either:
- pattern: 'Marshal.load(...)
'
- pattern: 'Marshal.restore(...)
'
- pattern: 'Oj.object_load(...)
'
- pattern: 'Oj.load($X)
'
message: "In Ruby, objects can be serialized into strings using various methods\
\ \nand later reconstituted into objects. The `load` and `object_load` \nmethods,\
\ associated with modules like Marshal and CSV, is particularly \nrisky when used\
\ to deserialize data from untrusted sources. \nIf an attacker is able to manipulate\
\ the serialized data, they could \nexecute arbitrary code on the system when\
\ the data is deserialized. \nThis vulnerability can lead to remote code execution\
\ (RCE), where an \nattacker gains the ability to execute commands on the host\
\ machine. \nThe Marshal and CSV modules are often used for serialization and\
\ \ndeserialization in Ruby but they do not inherently sanitize or validate \n\
the data being processed. This makes them unsafe for handling input from \nuntrusted\
\ sources.\n\nTo mitigate the risks associated with unsafe deserialization, it\
\ is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON\
\ for serialization/deserialization as JSON is considered \nsafer for data interchange\
\ between systems. However, it's crucial \nto use JSON securely by validating\
\ and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n\
```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize\
\ json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n\
\ return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing\
\ JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n#\
\ Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\"\
: 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n\
```\n\nAlways ensure that any data deserialized from JSON (or any format) is \n\
validated and sanitized according to the context of your application \nto prevent\
\ injection attacks or other security issues.\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Deserialization of untrusted data
category: security
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
security-severity: HIGH
technology:
- ruby
references:
- https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-env.yaml
- id: ruby_deserialization_rule-BadDeserialization
mode: taint
pattern-sources:
- pattern-either:
- pattern: params
- pattern: cookies
pattern-sinks:
- pattern-either:
- pattern: 'Marshal.load(...)
'
- pattern: 'Marshal.restore(...)
'
- pattern: 'Oj.object_load(...)
'
- pattern: 'Oj.load($X)
'
message: "In Ruby, objects can be serialized into strings using various methods\
\ \nand later reconstituted into objects. The `load` and `object_load` \nmethods,\
\ associated with modules like Marshal and CSV, is particularly \nrisky when used\
\ to deserialize data from untrusted sources. \nIf an attacker is able to manipulate\
\ the serialized data, they could \nexecute arbitrary code on the system when\
\ the data is deserialized. \nThis vulnerability can lead to remote code execution\
\ (RCE), where an \nattacker gains the ability to execute commands on the host\
\ machine. \nThe Marshal and CSV modules are often used for serialization and\
\ \ndeserialization in Ruby but they do not inherently sanitize or validate \n\
the data being processed. This makes them unsafe for handling input from \nuntrusted\
\ sources.\n\nTo mitigate the risks associated with unsafe deserialization, it\
\ is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON\
\ for serialization/deserialization as JSON is considered \nsafer for data interchange\
\ between systems. However, it's crucial \nto use JSON securely by validating\
\ and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n\
```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize\
\ json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n\
\ return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing\
\ JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n#\
\ Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\"\
: 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n\
```\n\nAlways ensure that any data deserialized from JSON (or any format) is \n\
validated and sanitized according to the context of your application \nto prevent\
\ injection attacks or other security issues.\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Deserialization of untrusted data
category: security
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
security-severity: HIGH
technology:
- ruby
references:
- https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization.yaml
- id: ruby_session_rule-AvoidSessionManipulation
mode: taint
pattern-sources:
- pattern: params
- pattern: cookies
- pattern: request.env
pattern-sinks:
- pattern: session[...]
message: "The application was found retrieving session data using user input. A\
\ \nmalicious user may be able to retrieve information from the session \nthat\
\ was not meant to be allowed. \nSession manipulation can occur when an application\
\ allows user-input in \nsession keys. Since sessions are typically considered\
\ a source of truth \n(e.g. to check the logged-in user or to match CSRF tokens),\
\ allowing an \nattacker to manipulate the session may lead to unintended behavior.\
\ \n\nTo mitigate this issue, never use user input as a session key. Instead,\
\ \nconsider an allow list approach to control access to session keys, \nensuring\
\ only predefined keys are accessible, and user input is not used\nto directly\
\ access the session key values. \n\nSecure Code Example:\n```\n# Define an allowed\
\ list of permitted session keys\nALLOWED_SESSION_KEYS = ['display_settings',\
\ 'locale']\n\nuser_provided_key = params[:key]\n\n# Validate the key against\
\ the list\nif ALLOWED_SESSION_KEYS.include?(user_provided_key)\n # Access the\
\ session value safely\n value = session[user_provided_key]\nelse\n raise \"\
Invalid session key provided.\"\nend\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Incorrect default permissions
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-276
security-severity: CRITICAL
references:
- https://brakemanscanner.org/docs/warning_types/session_manipulation/
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-session-manipulation.yaml
category: security
technology:
- rails
- id: ruby_sql_rule-CheckSQL
mode: taint
pattern-sources:
- pattern-either:
- pattern: 'cookies[...]
'
- patterns:
- pattern: 'cookies. ... .$PROPERTY[...]
'
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: 'params[...]
'
- pattern: 'request.env[...]
'
pattern-sanitizers:
- patterns:
- pattern-either:
- patterns:
- pattern: $X
- pattern-either:
- pattern-inside: ':$KEY => $X
'
- pattern-inside: '["...",$X,...]
'
- pattern: 'params[...].to_i
'
- pattern: 'params[...].to_f
'
- patterns:
- pattern: 'params[...] ? $A : $B
'
- metavariable-pattern:
metavariable: $A
patterns:
- pattern-not: 'params[...]
'
- metavariable-pattern:
metavariable: $B
patterns:
- pattern-not: 'params[...]
'
pattern-sinks:
- patterns:
- pattern: $X
- pattern-not-inside: '$P.where("...",...)
'
- pattern-not-inside: '$P.where(:$KEY => $VAL,...)
'
- pattern-either:
- pattern-inside: '$P.$M(...)
'
- pattern-inside: '$P.$M("...",...)
'
- pattern-inside: "class $P < ActiveRecord::Base\n ...\nend\n"
- metavariable-regex:
metavariable: $M
regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average)
message: "SQL Injection is a critical vulnerability that can lead to data or system\
\ compromise. By\ndynamically generating SQL query strings, user input may be\
\ able to influence the logic of\nthe SQL statement. This could lead to an adversary\
\ accessing information they should\nnot have access to, or in some circumstances,\
\ being able to execute OS functionality or code.\n\nTo mitigate this issue, always\
\ use parameterized queries or the \nActiveRecord query interface, which ensures\
\ that inputs are properly \nescaped, preventing SQL injection attacks. Avoid\
\ string interpolation \nor concatenation with user-controlled input for constructing\
\ SQL queries.\n\nSecure Code Example:\n```\n# Secure: Using parameterized queries\
\ with ActiveRecord\nuser_id = params[:id]\nUser.where(\"id = ?\", user_id)\n\n\
# Secure: Using ActiveRecord's query methods, which automatically handle parameterization\n\
# Converting to integer as an additional layer of input sanitization\nuser_id\
\ = params[:id].to_i \nUser.where(id: user_id)\n```\n"
languages:
- ruby
severity: ERROR
metadata:
shortDescription: Improper neutralization of special elements used in a SQL command
('SQL Injection')
category: security
cwe: CWE-89
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
technology:
- ruby
- rails
references:
- https://owasp.org/www-community/attacks/SQL_Injection
- https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-sql.yaml
- id: rules_lgpl_javascript_jwt_rule-hardcoded-jwt-secret
patterns:
- pattern-either:
- pattern-inside: 'const $JWT = require("jsonwebtoken");
...
'
- pattern-inside: 'const $JOSE = require("jose");
...
'
- pattern-inside: 'import $JWT from "jsonwebtoken"
...
'
- pattern-inside: 'import $JOSE from "jose"
...
'
- pattern-either:
- pattern: $JWT.sign($PAYLOAD, "...", ...)
- pattern: $JWT.verify($PAYLOAD, "...", ...)
- pattern: new $JOSE.SignJWT(...). ... .sign("...")
- pattern: 'var $TOKEN = new $JOSE.SignJWT(...). ...
...
$TOKEN. ... .sign("...")
'
- pattern: $JOSE.jwtVerify( $TKN, "...", ... )
- patterns:
- pattern-either:
- patterns:
- pattern-inside: "var $KEY = $X\n ...\n"
- pattern-either:
- pattern: new $JOSE.SignJWT(...). ... .sign($KEY)
- patterns:
- pattern: 'var $TOKEN = new $JOSE.SignJWT(...). ...
...
$TOKEN. ... .sign($KEY)
'
- pattern: $TOKEN. ... .sign($KEY)
- pattern: $JOSE.jwtVerify( $TKN, $KEY, ... )
- pattern: new $JOSE.SignJWT(...). ... .sign($X)
- patterns:
- pattern: 'var $TOKEN = new $JOSE.SignJWT(...). ...
...
$TOKEN. ... .sign($X)
'
- pattern: $TOKEN. ... .sign($X)
- pattern: $JOSE.jwtVerify( $TKN, $X, ... )
- metavariable-pattern:
metavariable: $X
pattern-either:
- pattern: new TextEncoder().encode( "...",... )
- pattern: Uint8Array.from("...", ...)
message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like\
\ JWT signing keys poses a significant security risk. \nIf the source code ends\
\ up in a public repository or is compromised, the secret is exposed. Attackers\
\ could then use the secret to \ngenerate forged tokens and access the system.\
\ Store it properly in an environment variable.\n\nHere are some recommended safe\
\ ways to access JWT secrets:\n - Use environment variables to store the secret\
\ and access it in code instead of hardcoding. This keeps it out of source control.\n\
\ - Use a secrets management service to securely store and tightly control access\
\ to the secret. Applications can request the secret at runtime.\n - For local\
\ development, use a .env file that is gitignored and access the secret from process.env.\n\
\nsample code snippet of accessing JWT secret from env variables\n```\n const\
\ token = jwt.sign(payload, process.env.SECRET, { algorithm: 'HS256' });\n```\n"
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-798
shortDescription: Use of hard-coded credentials
security-severity: HIGH
category: security
- id: rules_lgpl_javascript_jwt_rule-jwt-exposed-credentials
patterns:
- pattern-either:
- pattern-inside: 'const $JWT = require("jsonwebtoken");
...
'
- pattern-inside: 'const $JOSE = require("jose");
...
'
- pattern-inside: 'import $JWT from "jsonwebtoken"
...
'
- pattern-inside: 'import $JOSE from "jose"
...
'
- pattern-either:
- pattern: '$JWT.sign(<... {$PASSWORD: $VALUE} ...>, ...)'
- patterns:
- pattern: '$OBJ = <... {$PASSWORD: $VALUE} ...>
...
$TOKEN = $JWT.sign(<... $OBJ ...>, ...)
'
- pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...)
- patterns:
- pattern: '$OBJ. ... .$PASSWORD = ...
...
$TOKEN = $JWT.sign(<... $OBJ ...>, ...)
'
- pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...)
- pattern: 'new $JOSE.SignJWT(<... {$PASSWORD: $VALUE} ...>)'
- patterns:
- pattern: '$OBJ = <... {$PASSWORD: $VALUE} ...>
...
new $JOSE.SignJWT(<... $OBJ ...>)
'
- pattern: new $JOSE.SignJWT(<... $OBJ ...>)
- patterns:
- pattern: '$OBJ. ... .$PASSWORD = ...
...
new $JOSE.SignJWT(<... $OBJ ...>)
'
- pattern: new $JOSE.SignJWT(<... $OBJ ...>)
- metavariable-regex:
metavariable: $PASSWORD
regex: (?i)\b(?:.*password.*)\b
severity: ERROR
languages:
- javascript
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: HIGH
category: security
message: "The application is storing a password in the JWT token payload. Storing\
\ \npasswords in JWT token payloads is an insecure practice that can lead to \n\
compromised credentials. \n\nThe password transmitted in the JWT payload is not\
\ encrypted and therefore \nvisible to anyone who intercepts the token. It is\
\ recommended to avoid storing \nsensitive information like passwords in JWTs.\
\ Instead, reference user identifiers \nthat map to credentials stored securely\
\ on the server.This helps to mitigate the \nrisk of exposing passwords through\
\ JWT tokens that could be intercepted or leaked.\n\nSecure code example of secure\
\ JWT signing:\n```\nrouter.route(\"/jsonwebtoken/1\").get((req, res) => {\n \
\ // any payload without passwords or any other sensitive data will be secure\n\
\ const payload = { user_id: 123, username: 'john_doe' };\n const token = jwt.sign(payload,\
\ secretKey, { algorithm: 'HS256' });\n console.log('Generated Token:', token);\n\
\ res.send({ token })\n})\n```"
- id: rules_lgpl_javascript_jwt_rule-jwt-exposed-data
patterns:
- pattern-inside: 'require(''jose'')
...
'
- pattern-either:
- patterns:
- pattern-inside: function (...,$INPUT,...) {...}
- pattern-either:
- pattern: $JOSE.JWT.sign($INPUT,...)
- pattern: $JWT.sign($INPUT,...)
- patterns:
- pattern-inside: function $F(...,$INPUT,...) {...}
- pattern-either:
- pattern: $JOSE.JWT.sign($INPUT,...)
- pattern: $JWT.sign($INPUT,...)
message: 'The object is passed strictly to jose.JWT.sign(...). Make sure that sensitive
information is not exposed through JWT token payload.
'
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: HIGH
category: security
languages:
- javascript
- id: rules_lgpl_javascript_jwt_rule-jwt-not-revoked
patterns:
- pattern-inside: '$JWT = require(''express-jwt'')
...
'
- pattern: $JWT(...)
- pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...)
- pattern-not-inside: '$OPTS = <... {isRevoked:...} ...>;
...
$JWT($OPTS,...)'
message: 'No token revoking configured for `express-jwt`. A leaked token could still
be used and unable to be revoked. Consider using function as the `isRevoked` option.
'
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: HIGH
category: security
- id: rules_lgpl_javascript_jwt_rule-node-jwt-none-algorithm
mode: taint
pattern-sources:
- pattern: $JWT = require("jsonwebtoken")
- pattern: import $JWT from "jsonwebtoken"
pattern-sinks:
- pattern: $JWT.verify($P, $X, {...,algorithms:[...,'none',...],...},...)
- pattern: $JWT.sign($P, $X, {...,algorithm:'none',...},...)
message: "Use of `{algorithm:'none'}` detected with `jsonwebtoken`. \nUsing none\
\ as the algorithm for jsonwebtoken can directly impact the integrity of the information\
\ transfer through the JWT token.\nConsider using a secure algorithm to sign your\
\ JWT token such as HMAC or RSA.\nSome safe usage examples:\n```\nlet token =\
\ jwt.sign({user:\"user1\"}, 'secret', {algorithm: 'HS256'}); \n```\nUsing a\
\ secure algorithm can protect the integrity of the token information. \nAvoid\
\ using none as the algorithm when signing jwt tokens since it can violate the\
\ integrity of the JWT information.\n"
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-327
shortDescription: Use of a broken or risky cryptographic algorithm
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_jwt_rule-jwt-express-hardcoded
patterns:
- pattern-either:
- pattern-inside: 'import { ..., $JWT,... } from ''express-jwt'';
...
'
- pattern-inside: 'var {..., expressjwt: $JWT,... } = require(''express-jwt'');
...
'
- pattern-either:
- pattern: $JWT(<...{...,secret:"...",...}...>)
- patterns:
- pattern-inside: '$OPTS = <... {secret: "..."} ...>;
...
'
- pattern: $JWT(<... $OPTS ...>,...)
- patterns:
- pattern-inside: '$OPTS = <... {secret: "..."} ...>;
...
$OPTS2 = <... $OPTS ...>;
...
'
- pattern: $JWT(<... $OPTS2 ...>,...)
message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like\
\ JWT signing keys poses a significant security risk. \nIf the source code ends\
\ up in a public repository or is compromised, the secret is exposed. Attackers\
\ could then use the secret to \ngenerate forged tokens and access the system.\
\ Store it properly in an environment variable.\n\nHere are some recommended safe\
\ ways to access JWT secrets:\n - Use environment variables to store the secret\
\ and access it in code instead of hardcoding. This keeps it out of source control.\n\
\ - Use a secrets management service to securely store and tightly control access\
\ to the secret. Applications can request the secret at runtime.\n - For local\
\ development, use a .env file that is gitignored and access the secret from process.env.\n\
\nsample code snippet of accessing JWT secret from env variables\n```\nrouter.route(\"\
/auth-route-1\").get(\n jwt({ secret: process.env.secret, algorithms: ['HS256']\
\ }),\n (req, res) => {\n res.send('Token is valid');\n }\n);\n```\n"
severity: ERROR
languages:
- javascript
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_ssrf_rule-wkhtmltoimage-ssrf
mode: taint
pattern-sources:
- patterns:
- pattern: "function($REQ, $RES, ...){\n ...\n}\n"
- focus-metavariable: $REQ
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: '$W = require(''wkhtmltoimage'')
...
'
- pattern-inside: 'import $W from ''wkhtmltoimage''
...
'
- pattern: '$W.generate(...)
'
pattern-sanitizers:
- patterns:
- pattern-inside: "if($ALLOWED.includes($URL)){\n ...\n}\n"
message: "This rule detects instances where user-controlled URLs are passed directly\n\
to the `generate` function of `wkhtmltoimage` library. This practice can\nlead\
\ to Server Side Request Forgery (SSRF) vulnerabilities, where an\nattacker can\
\ induce the server to make requests to arbitrary URLs. This\ncan potentially\
\ expose internal services within the network or lead to\ninformation disclosure.\n\
\nTo mitigate this vulnerability, ensure that URLs are safe and intended for \n\
public access. Implementing allowlists for acceptable domains or schemes can \n\
significantly reduce the risk of SSRF. Additionally, consider using server-side\
\ \nproxy services that restrict the outgoing requests to trusted domains and\
\ \nresources.\n\nSecure Code Example:\n```\nconst wkhtmltoimage = require('wkhtmltoimage');\n\
\n// Define an allowlist of domains\nconst allowedDomains = ['example.com', 'trusted-source.com'];\n\
\napp.post('/generate-image', (req, res) => {\n const userInputUrl = req.body.url;\
\ \n const parsedUrl = new URL(userInputUrl);\n\n // Check if the domain is\
\ in the allowlist\n if (allowedDomains.includes(parsedUrl.hostname)) {\n \
\ wkhtmltoimage.generate(userInputUrl, { output: 'output.jpg' }, \n function\
\ (err, stream) {\n if (err) {\n return res.status(500).send('Error\
\ generating image');\n }\n // Send a success response or the\
\ image itself\n res.status(200).send('Image generated successfully');\n\
\ });\n } else {\n res.status(400).send('URL is not allowed due to\
\ security policies.');\n }\n});\n```\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A1:2017-Injection
- A10:2021-Server-Side Request Forgery
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_ssrf_rule-playwright-ssrf
patterns:
- pattern-inside: 'require(''playwright'')
...
'
- pattern-either:
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $PAGE.goto(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.goto(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.setContent(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluate(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluate($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluate($CODE,..., <... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY.$FOO ...>, ...)
- pattern: $CONTEXT.addInitScript(<... $REQ.$BODY ...>,...)
- pattern: $CONTEXT.addInitScript(<... $REQ.$BODY.$FOO ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.goto(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.goto(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate($CODE,..., <... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate($CODE,..., <... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$CONTEXT.addInitScript($INPUT,...)
'
message: 'If unverified user data can reach the `puppeteer` methods it can result
in Server-Side Request Forgery vulnerabilities.
'
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
- id: rules_lgpl_javascript_ssrf_rule-phantom-ssrf
patterns:
- pattern-inside: 'require(''phantom'')
...
'
- pattern-either:
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $PAGE.open(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.open(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.openUrl(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.openUrl(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluateJavaScript(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluateJavaScript(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.property("content",<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.property("content",<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.open(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.open(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.openUrl(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.openUrl(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateJavaScript(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateJavaScript(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.property("content",<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.property("content",<... $INPUT ...>,...)'
message: '''If unverified user data can reach the `phantom` methods it can result
in Server-Side Request Forgery vulnerabilities.
''
'
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
- id: rules_lgpl_javascript_ssrf_rule-node-ssrf
mode: taint
pattern-sources:
- patterns:
- focus-metavariable: $REQ
- pattern: function ($REQ, $RES, ...) {...}
- patterns:
- focus-metavariable: $REQ
- pattern: function $FUNC($REQ, $RES, ...) {...}
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n...\n} \n"
- pattern: '$A = $VALIDATION
...
if($A){
...
}
'
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.includes(...) \n"
- pattern: '$AL.indexOf(...) !== -1
'
- pattern: '$AL.find(...) !== undefined
'
- pattern: '$ALS.has(...)
'
pattern-sinks:
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: '$NEEDLE = require(''needle'');
...
'
- pattern-inside: 'import $NEEDLE from ''needle''
...
'
- pattern-either:
- pattern: $NEEDLE('$VERB', $REQ, ...)
- pattern: $NEEDLE.$VERB($REQ, ...)
- metavariable-regex:
metavariable: $VERB
regex: ^(get|put|post|patch|delete|head)$
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: '$AXIOS = require(''axios'');
...
'
- pattern-inside: 'import $AXIOS from ''axios''
...
'
- pattern-either:
- patterns:
- metavariable-regex:
metavariable: $URL
regex: ^(url|baseURL)$
- pattern-either:
- pattern: '$AXIOS({ ..., $URL: $REQ, ...})
'
- pattern: '$AXIOS.create({ ..., $URL: $REQ, ...})
'
- patterns:
- pattern: $AXIOS.$VERB($REQ, ...)
- metavariable-regex:
metavariable: $VERB
regex: ^(get|put|post|patch|delete|head)$
- patterns:
- pattern: axios($REQ)
- pattern-not-inside: axios({...})
- pattern: 'axios.defaults.baseURL = $REQ
'
- patterns:
- focus-metavariable: $URL
- pattern-either:
- pattern-inside: '{..., request, ... } = require(''urllib'');
...
'
- pattern-inside: 'import {..., request, ... } from ''urllib''
...
'
- pattern: request($URL, ...)
- patterns:
- focus-metavariable: $URL
- pattern-either:
- pattern-inside: '{..., HttpClient, ... } = require(''urllib'');
...
'
- pattern-inside: 'import {..., HttpClient, ... } from ''urllib''
...
'
- pattern: "$HTTPCLIENT = new HttpClient({\n allowH2: true,\n\
\ });\n...\n$HTTPCLIENT.request($URL, ...)\n"
- patterns:
- focus-metavariable: $URL
- pattern-either:
- pattern-inside: '$URLLIIB = require(''urllib'');
...
'
- pattern-inside: 'import $URLLIIB from ''urllib''
...
'
- pattern: $URLLIIB.request($URL, ...)
- patterns:
- pattern-either:
- pattern-inside: "$SA = require('superagent');\n ...\n"
- pattern-inside: 'import $SA from ''superagent''
...
'
- patterns:
- pattern: $SA.$VERB(...)
- metavariable-regex:
metavariable: $VERB
regex: ^(get|put|post|patch|delete|head)$
- patterns:
- pattern-either:
- patterns:
- pattern: fetch($REQ,...)
- focus-metavariable: $REQ
- pattern-not: fetch(new Request(...))
- patterns:
- pattern: fetch(new Request($REQ,...))
- focus-metavariable: $REQ
- pattern-not-inside: '$REQUEST_OBJ = new Request(...)
...
fetch($REQUEST_OBJ)
'
- patterns:
- pattern: new Request($REQ,...)
- focus-metavariable: $REQ
- pattern-inside: '$REQUEST_OBJ = new Request($REQ,...)
...
fetch($REQUEST_OBJ)
'
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: '$HTTP = require(''$PKG'');
...
'
- pattern-inside: 'import $HTTP from $PKG
...
'
- metavariable-regex:
metavariable: $PKG
regex: ^(http|https)$
- metavariable-regex:
metavariable: $METHOD
regex: ^(get|request)$
- pattern-either:
- patterns:
- pattern: $HTTP.$METHOD($REQ, ...)
- pattern-not-inside: '$HTTP.$METHOD({...}, ...)
'
- pattern-not-inside: '$OPTS = {...}
...
$HTTP.$METHOD($OPTS, ...)
'
- pattern: '$HTTP.$METHOD({..., hostname: $REQ}, ...)
'
- pattern: '$OPTS = {..., hostname: $REQ, ...}
...
$HTTP.$METHOD($OPTS, ...)
'
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: '{ ..., io, ... } = require(''socket.io-client'');
...
'
- pattern-inside: 'import { ..., io, ... } from ''socket.io-client''
...
'
- pattern: io($REQ, ...)
- patterns:
- focus-metavariable: $HOST
- pattern-either:
- pattern-inside: '$NET = require(''net'');
...
'
- pattern-inside: 'import $NET from ''net''
...
'
- metavariable-regex:
metavariable: $METHOD
regex: ^(connect|createConnection)$
- pattern-either:
- pattern: $NET.$METHOD($PORT, $HOST, ...)
- pattern: '$NET.$METHOD({..., host: $HOST, ...}, ...)
'
- pattern: '$OPTS = {..., host: $HOST, ...}
...
$NET.$METHOD($OPTS, ...)
'
- pattern: '$CLIENT = new $NET.Socket()
...
$CLIENT.$METHOD($PORT, $HOST, ...)
'
- patterns:
- pattern-either:
- pattern-inside: '$BENT = require(''bent'');
...
'
- pattern-inside: 'import $BENT from ''bent'';
...
'
- pattern: $BENT(...)
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: '$BENT = require(''bent'');
...
$MTD = $BENT(...)
'
- pattern-inside: 'import $BENT from ''bent'';
...
$MTD = $BENT(...)
'
- pattern: $MTD($REQ, ...)
- patterns:
- pattern-either:
- pattern-inside: '$BENT = require(''bent'');
...
$GETBENT = $BENT(''$PKG'')
...
'
- pattern-inside: 'import $BENT from ''bent'';
...
$GETBENT = $BENT(''$PKG'')
...
'
- pattern: $GETBENT(...)
- metavariable-regex:
metavariable: $PKG
regex: ^(json|buffer)$
- patterns:
- focus-metavariable: $REQ
- pattern-either:
- pattern-inside: 'import $GOT from ''got'';
...
'
- pattern: $GOT.$VERB($REQ, ...)
- metavariable-regex:
metavariable: $VERB
regex: ^(get|put|post|patch|delete|head)$
- patterns:
- focus-metavariable: $URL
- pattern-either:
- pattern-inside: '$REQUEST = require(''request'');
...
'
- pattern-inside: 'import $REQUEST from ''request'';
...
'
- pattern: $REQUEST($URL, ...)
message: "This application allows user-controlled URLs to be passed directly to\
\ HTTP client libraries. \nThis can result in Server-Side Request Forgery (SSRF).\n\
SSRF refers to an attack where the attacker can abuse functionality on \nthe server\
\ to force it to make requests to other internal systems within your \ninfrastructure\
\ that are not directly exposed to the internet. \nThis allows the attacker to\
\ access internal resources they do not have direct access to.\n\nSome risks of\
\ SSRF are:\n\n- Access and manipulation of internal databases, APIs, or administrative\
\ panels\n- Ability to scan internal network architecture and services\n- Can\
\ be used to pivot attacks into the internal network\n- Circumvent network segregation\
\ and firewall rules\n\nTo avoid this, try using hardcoded HTTP request calls\
\ or a whitelisting object to \ncheck whether the user input is trying to access\
\ allowed resources or not.\n\nHere is an example:\n```\nvar whitelist = [\n \
\ \"https://example.com\", \n \"https://example.com/sample\"\n]\n\napp.get('/ssrf/node-ssrf/axios/safe/3',\
\ function (req, res) {\n if(whitelist.includes(req.query.url)){\n axios.get(url,\
\ {})\n .then(function (response) {\n console.log(response);\n\
\ })\n .catch(function (response) {\n console.log(response);\
\ \n })\n }\n});\n``` \nFor more information on SSRF see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html\n"
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: HIGH
category: security
- id: rules_lgpl_javascript_ssrf_rule-wkhtmltopdf-ssrf
patterns:
- pattern-inside: 'require(''wkhtmltopdf'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$INP = <... $REQ.$VAR ...>;
...
wkhtmltopdf(<... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$VAR.$FOO ...>;
...
wkhtmltopdf(<... $INP ...>, ...)
'
- pattern: 'wkhtmltopdf(<... $REQ.$VAR ...>, ...)
'
- pattern: 'wkhtmltopdf(<... $REQ.$VAR.$FOO ...>, ...)
'
message: 'User controlled URL reached to `wkhtmltopdf` can result in Server Side
Request Forgery (SSRF).
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_ssrf_rule-puppeteer-ssrf
patterns:
- pattern-inside: 'require(''puppeteer'')
...
'
- pattern-either:
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $PAGE.goto(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.goto(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluate(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluate($CODE,<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluate($CODE,<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$BODY ...>,...)
- pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.goto(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.goto(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.setContent(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate($CODE,<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate($CODE,<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle($CODE,<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle($CODE,<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...)
'
message: 'If unverified user data can reach the `puppeteer` methods it can result
in Server-Side Request Forgery vulnerabilities.
'
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-918
shortDescription: Server-side request forgery (SSRF)
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
- id: rules_lgpl_javascript_database_rule-node-nosqli-injection
patterns:
- pattern-not-inside: '$SANITIZE = require(''mongo-sanitize'')
...
$SANITIZE(...)
...
'
- pattern-not-inside: 'import $SANITIZE from ''mongo-sanitize''
...
$SANITIZE(...)
...
'
- pattern-not: '$OBJ.findOne({$KEY : String(...).$FUNC()}, ...)
'
- pattern-not: '$OBJ.findOne({$KEY : String(...).$FUNC}, ...)
'
- pattern-not: '$OBJ.findOne({$KEY : String(...)}, ...)
'
- pattern-either:
- pattern: '$OBJ.findOne({$KEY : <... $REQ.$FOO.$BAR ...> }, ...)
'
- pattern: '$OBJ.findOne({$KEY: <... $REQ.$FOO ...> }, ...)
'
- pattern: '$INP = <... $REQ.$FOO.$BAR ...>;
...
$OBJ.findOne({$KEY : <... $INP ...> }, ...)
'
- pattern: '$INP = <... $REQ.$FOO ...>;
...
$OBJ.findOne({$KEY: <... $INP ...> }, ...)
'
- pattern: '$QUERY = {$KEY: <... $REQ.$FOO.$BAR ...>};
...
$OBJ.findOne($QUERY, ...)
'
- pattern: '$QUERY = {$KEY: <... $REQ.$FOO ...>};
...
$OBJ.findOne($QUERY, ...)
'
- pattern: '$INP = <... $REQ.$FOO.$BAR ...>;
...
$QUERY = {$KEY : <... $INP ...> };
...
$OBJ.findOne(<... $QUERY ...>, ...)
'
- pattern: '$INP = <... $REQ.$FOO ...>;
...
$QUERY = {$KEY : <... $INP ...> };
...
$OBJ.findOne(<... $QUERY ...>, ...)
'
- pattern: '$QUERY[$KEY] = <... $REQ.$FOO.$BAR ...>;
...
$OBJ.findOne($QUERY, ...)
'
- pattern: '$QUERY[$KEY] = <... $REQ.$FOO ...>;
...
$OBJ.findOne($QUERY, ...)
'
- pattern: '$INP = <... $REQ.$FOO.$BAR ...>;
...
$QUERY[$KEY] = <... $INP ...>;
...
$OBJ.findOne(<... $QUERY ...>, ...)
'
- pattern: '$INP = <... $REQ.$FOO ...>;
...
$QUERY[$KEY] = <... $INP ...>;
...
$OBJ.findOne(<... $QUERY ...>, ...)
'
message: 'Untrusted user input in findOne() function can result in NoSQL Injection.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-943
shortDescription: Improper neutralization of special elements in data query logic
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_database_rule-node-knex-sqli-injection
patterns:
- pattern-either:
- pattern-inside: '$KNEX = require(''knex'')
...
'
- pattern-inside: '$KNEX = require(''knex'')(...)
...
'
- pattern-either:
- pattern: '$K.raw(<... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$K.raw(<... $REQ.$QUERY ...>, ...)
'
- pattern: '$SQL = <... $REQ.$QUERY.$VAR ...>;
...
$K.raw(<... $SQL ...>, ...)
'
- pattern: '$SQL = <... $REQ.$QUERY ...>;
...
$K.raw(<... $SQL ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
$SQL = <... $INP ...>;
...
$K.raw(<... $SQL ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$SQL = <... $INP ...>;
...
$K.raw(<... $SQL ...>, ...)
'
- pattern: '$K.whereRaw(<... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$K.whereRaw(<... $REQ.$QUERY ...>, ...)
'
- pattern: '$SQL = <... $REQ.$QUERY.$VAR ...>;
...
$K.whereRaw(<... $SQL ...>, ...)
'
- pattern: '$SQL = <... $REQ.$QUERY ...>;
...
$K.whereRaw(<... $SQL ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
$SQL = <... $INP ...>;
...
$K.whereRaw(<... $SQL ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$SQL = <... $INP ...>;
...
$K.whereRaw(<... $SQL ...>, ...)
'
message: 'Untrusted input concatinated with raw SQL query using knex raw() or whereRaw()
functions can result in SQL Injection.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-89
shortDescription: Improper neutralization of special elements used in an SQL command
(SQL Injection)
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_database_rule-sequelize-tls
message: '''The Sequelize connection string indicates that database server does
not use TLS. Non TLS connections are susceptible to man in the middle (MITM) attacks.''
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
security-severity: MEDIUM
category: security
patterns:
- pattern: "{\n host: $HOST,\n database: $DATABASE,\n dialect: $DIALECT\n }\n"
- pattern-not: "{\n host: $HOST,\n database: $DATABASE,\n dialect: \"postgres\"\
,\n dialectOptions: {\n ssl: true\n }\n}\n"
- pattern-not: "{\n host: $HOST,\n database: $DATABASE,\n dialect: $DIALECT,\n\
\ dialectOptions: {\n ssl: { ... }\n }\n}\n"
- metavariable-regex:
metavariable: $DIALECT
regex: '[''"](mariadb|mysql|postgres|oracle)[''"]'
- id: rules_lgpl_javascript_database_rule-node-nosqli-js-injection
patterns:
- pattern-either:
- pattern: '$OBJ.$FUNC({$where: <... $REQ.$FOO.$BAR ...>}, ...)
'
- pattern: '$OBJ.$FUNC({$where: <... $REQ.$QUERY ...>}, ...)
'
- pattern: '$NSQL = <... $REQ.$QUERY.$...>;
...
$OBJ.$FUNC({$where: <... $NSQL ...>}, ...)
'
- pattern: '$NSQL = <... $REQ.$QUERY ...>;
...
$OBJ.$FUNC({$where: <... $NSQL ...>}, ...)
'
- pattern: '$INP = $REQ.$FOO.$BAR;
...
$QRY = {$where: <... $INP ...>};
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
- pattern: '$INP = $REQ.$FOO;
...
$QRY = {$where: <... $INP ...>};
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
- pattern: '$QRY["$where"] = <... $REQ.$FOO ...>;
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
- pattern: '$QRY["$where"] = <... $REQ.$FOO.$BAR ...>;
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
- pattern: '$INP = $REQ.$FOO;
...
$QRY["$where"] = <... $INP ...>;
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
- pattern: '$INP = $REQ.$FOO.$BAR;
...
$QRY["$where"] = <... $INP ...>;
...
$OBJ.$FUNC(<... $QRY ...>, ...)
'
message: 'Untrusted user input in MongoDB $where operator can result in NoSQL JavaScript
Injection.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-943
shortDescription: Improper neutralization of special elements in data query logic
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_database_rule-sequelize-weak-tls
message: '''The Sequelize connection string indicates that an older version of TLS
is in use. TLS1.0 and TLS1.1 are deprecated and should be used. By default, Sequelize
use TLSv1.2 but it''''s recommended to use TLS1.3. Not applicable to SQLite database.''
'
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-757
shortDescription: Selection of Less-Secure Algorithm During Negotiation (Algorithm
Downgrade)
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
patterns:
- pattern-inside: "{\n host: $HOST,\n database: $DATABASE,\n dialect: $DIALECT,\n\
\ dialectOptions:\n { ssl: ... }\n }\n"
- pattern-either:
- pattern: "{\n minVersion: 'TLSv1'\n}\n"
- pattern: "{\n minVersion: 'TLSv1.1'\n}\n"
- metavariable-regex:
metavariable: $DIALECT
regex: '[''"](mariadb|mysql|postgres)[''"]'
- id: rules_lgpl_javascript_database_rule-node-sqli-injection
patterns:
- pattern-inside: 'require(''$LIB'')
...
'
- metavariable-regex:
metavariable: $LIB
regex: \b(sql-client|mysql|pg|mssql|oracledb|sequelize)\b
- pattern-not: '$CON.query("..." + "...", ...)
'
- pattern-not: '$SQL = "...";
...
$CON.query(<... $SQL ...>, ...)
'
- pattern-either:
- pattern: '$CON.query(<... $REQ.$QUERY ...>, ...)
'
- pattern: '$SQL = <... $REQ.$QUERY ...>;
...
$CON.query(<... $SQL ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$SQL = <... $INP ...>;
...
$CON.query(<... $SQL ...>, ...)
'
- pattern: '$CON.query(`...${...}...`, ...)
'
- pattern: '$CON.query("..."+...+"...", ...)
'
- pattern: '$SQL = <... $INP ...>;
...
$CON.query(<... $SQL ...>, ...)
'
message: 'Untrusted input concatinated with raw SQL query can result in SQL Injection.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-89
shortDescription: Improper neutralization of special elements used in an SQL command
(SQL Injection)
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_database_rule-sequelize-tls-cert-validation
message: "The Sequelize connection string indicates that TLS certificate validation\
\ \nof database server is disabled. This is equivalent to not having TLS. An \n\
attacker can present any invalid certificate and Sequelize will make database\
\ \nconnection ignoring certificate errors. This setting make the connection\n\
susceptible to man in the middle (MITM) attacks. Not applicable to SQLite database.\n"
severity: ERROR
languages:
- javascript
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-295
shortDescription: Improper certificate validation
security-severity: HIGH
category: security
patterns:
- pattern: "{\n host: $HOST,\n database: $DATABASE,\n dialect: $DIALECT,\n dialectOptions:\
\ {\n ssl: {\n rejectUnauthorized: false\n }\n }\n }\n"
- metavariable-regex:
metavariable: $DIALECT
regex: '[''"](mariadb|mysql|postgres)[''"]'
- id: rules_lgpl_javascript_crypto_rule-node-weak-crypto
patterns:
- pattern-either:
- pattern: '$X.createCipher(''des'', ...)
'
message: 'A weak or broken cryptographic algorithm was identified. Using these functions
will introduce vulnerabilities or downgrade the security of your application.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-327
shortDescription: Use of a broken or risky cryptographic algorithm
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_crypto_rule-node-tls-reject
patterns:
- pattern-either:
- pattern: '$X.env.NODE_TLS_REJECT_UNAUTHORIZED = $VAL
'
- pattern: '$X.env[''NODE_TLS_REJECT_UNAUTHORIZED'']= $VAL
'
- metavariable-pattern:
metavariable: $VAL
pattern-either:
- pattern: '''0''
'
- pattern: '0
'
message: "The application sets NODE_TLS_REJECT_UNAUTHORIZED to '0', which instructs\
\ Node.js to disable TLS/SSL certificate validation. \nThis configuration allows\
\ the application to accept self-signed certificates or certificates from untrusted\
\ authorities, \nundermining the TLS security model. Disabling TLS/SSL certificate\
\ validation compromises the integrity and confidentiality \nof data in transit\
\ between the client and server. It makes the application vulnerable to man-in-the-middle\
\ (MITM) attacks, \nwhere an attacker could intercept or alter the data being\
\ exchanged.\n\nMitigation Strategy:\nDo not disable TLS/SSL certificate validation\
\ in production environments. Ensure that NODE_TLS_REJECT_UNAUTHORIZED is \nset\
\ to '1' or is removed entirely from the production configuration (as the default\
\ configuration of validating SSL \ncertificate is safe).\n\nSecure Code Example:\n\
```\nconst https = require('https')\nprocess.env['NODE_TLS_REJECT_UNAUTHORIZED']\
\ = '1'\nconst req = https.request(options, res => {\n let data = ''\n res.on('data',\
\ chunk => {\n data += chunk\n })\n res.on('end', () => {\n console.log('Response\
\ Body:', data)\n })\n})\nreq.end()\n```\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-295
shortDescription: Improper Certificate Validation
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_crypto_rule-node-aes-noiv
patterns:
- pattern-either:
- pattern: '$X.createCipheriv("=~/^aes-/i", $KEY, "", ...)
'
message: 'AES algorithms requires an initialization vector (IV). Providing no or
null IV in some implementation results to a 0 IV. Use of a deterministic IV makes
dictionary attacks easier.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-327
shortDescription: Use of a broken or risky cryptographic algorithm
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_crypto_rule-node-timing-attack
patterns:
- pattern-not: if ($Z == null) { ... };
- pattern-not: if ($Z === null) { ... };
- pattern-not: if ($Z != null) { ... };
- pattern-not: if ($Z !== null) { ... };
- pattern-not: if ($Q != undefined) { ... };
- pattern-not: if ($Q !== undefined) { ... };
- pattern-not: if ($Q == undefined) { ... };
- pattern-not: if ($Q === undefined) { ... };
- pattern-not: return $Y == null;
- pattern-not: return $Y === null;
- pattern-not: return $Y != null;
- pattern-not: return $Y !== null;
- pattern-not: return $Y == undefined;
- pattern-not: return $Y === undefined;
- pattern-not: return $Y != undefined;
- pattern-not: return $Y !== undefined;
- pattern-either:
- pattern: "if (password == $X) {\n ...\n}\n"
- pattern: "if ($X == password) {\n ...\n}\n"
- pattern: "if (password === $X) {\n ...\n}\n"
- pattern: "if ($X === password) {\n ...\n}\n"
- pattern: "if (pass == $X) {\n ...\n}\n"
- pattern: "if ($X == pass) {\n ...\n}\n"
- pattern: "if (pass === $X) {\n ...\n}\n"
- pattern: "if ($X === pass) {\n ...\n}\n"
- pattern: "if (secret == $X) {\n ...\n}\n"
- pattern: "if ($X == secret) {\n ...\n}\n"
- pattern: "if (secret === $X) {\n ...\n}\n"
- pattern: "if ($X === secret) {\n ...\n}\n"
- pattern: "if (api == $X) {\n ...\n}\n"
- pattern: "if ($X == api) {\n ...\n}\n"
- pattern: "if (api === $X) {\n ...\n}\n"
- pattern: "if ($X === api) {\n ...\n}\n"
- pattern: "if (apiKey == $X) {\n ...\n}\n"
- pattern: "if ($X == apiKey) {\n ...\n}\n"
- pattern: "if (apiKey === $X) {\n ...\n}\n"
- pattern: "if ($X === apiKey) {\n ...\n}\n"
- pattern: "if (apiSecret == $X) {\n ...\n}\n"
- pattern: "if ($X == apiSecret) {\n ...\n}\n"
- pattern: "if (apiSecret === $X) {\n ...\n}\n"
- pattern: "if ($X === apiSecret) {\n ...\n}\n"
- pattern: "if (token == $X) {\n ...\n}\n"
- pattern: "if ($X == token) {\n ...\n}\n"
- pattern: "if (token === $X) {\n ...\n}\n"
- pattern: "if ($X === token) {\n ...\n}\n"
- pattern: "if (hash == $X) {\n ...\n}\n"
- pattern: "if ($X == hash) {\n ...\n}\n"
- pattern: "if (hash === $X) {\n ...\n}\n"
- pattern: "if ($X === hash) {\n ...\n}\n"
- pattern: "if (auth_token == $X) {\n ...\n}\n"
- pattern: "if ($X == auth_token) {\n ...\n}\n"
- pattern: "if (auth_token === $X) {\n ...\n}\n"
- pattern: "if ($X === auth_token) {\n ...\n}\n"
- pattern: "if (password != $X) {\n ...\n}\n"
- pattern: "if ($X != password) {\n ...\n}\n"
- pattern: "if (password !== $X) {\n ...\n}\n"
- pattern: "if ($X !== password) {\n ...\n}\n"
- pattern: "if (pass != $X) {\n ...\n}\n"
- pattern: "if ($X != pass) {\n ...\n}\n"
- pattern: "if (pass !== $X) {\n ...\n}\n"
- pattern: "if ($X !== pass) {\n ...\n}\n"
- pattern: "if (secret != $X) {\n ...\n}\n"
- pattern: "if ($X != secret) {\n ...\n}\n"
- pattern: "if (secret !== $X) {\n ...\n}\n"
- pattern: "if ($X !== secret) {\n ...\n}\n"
- pattern: "if (api != $X) {\n ...\n}\n"
- pattern: "if ($X != api) {\n ...\n}\n"
- pattern: "if (api !== $X) {\n ...\n}\n"
- pattern: "if ($X !== api) {\n ...\n}\n"
- pattern: "if (apiKey != $X) {\n ...\n}\n"
- pattern: "if ($X != apiKey) {\n ...\n}\n"
- pattern: "if (apiKey !== $X) {\n ...\n}\n"
- pattern: "if ($X !== apiKey) {\n ...\n}\n"
- pattern: "if (apiSecret != $X) {\n ...\n}\n"
- pattern: "if ($X != apiSecret) {\n ...\n}\n"
- pattern: "if (apiSecret !== $X) {\n ...\n}\n"
- pattern: "if ($X !== apiSecret) {\n ...\n}\n"
- pattern: "if (token != $X) {\n ...\n}\n"
- pattern: "if ($X != token) {\n ...\n}\n"
- pattern: "if (token !== $X) {\n ...\n}\n"
- pattern: "if ($X !== token) {\n ...\n}\n"
- pattern: "if (hash != $X) {\n ...\n}\n"
- pattern: "if ($X != hash) {\n ...\n}\n"
- pattern: "if (hash !== $X) {\n ...\n}\n"
- pattern: "if ($X !== hash) {\n ...\n}\n"
- pattern: "if (auth_token != $X) {\n ...\n}\n"
- pattern: "if ($X != auth_token) {\n ...\n}\n"
- pattern: "if (auth_token !== $X) {\n ...\n}\n"
- pattern: "if ($X !== auth_token) {\n ...\n}\n"
- pattern: 'return $X === auth_token;
'
- pattern: 'return auth_token === $X;
'
- pattern: 'return $X === token;
'
- pattern: 'return token === $X;
'
- pattern: 'return $X === hash;
'
- pattern: 'return hash === $X;
'
- pattern: 'return $X === password;
'
- pattern: 'return password === $X;
'
- pattern: 'return $X === pass;
'
- pattern: 'return pass === $X;
'
- pattern: 'return $X === apiKey;
'
- pattern: 'return apiKey === $X;
'
- pattern: 'return $X === apiSecret;
'
- pattern: 'return apiSecret === $X;
'
- pattern: 'return $X === api_key;
'
- pattern: 'return api_key === $X;
'
- pattern: 'return $X === api_secret;
'
- pattern: 'return api_secret === $X;
'
- pattern: 'return $X === secret;
'
- pattern: 'return secret === $X;
'
- pattern: 'return $X === api;
'
- pattern: 'return api === $X;
'
- pattern: 'return $X == auth_token;
'
- pattern: 'return auth_token == $X;
'
- pattern: 'return $X == token;
'
- pattern: 'return token == $X;
'
- pattern: 'return $X == hash;
'
- pattern: 'return hash == $X;
'
- pattern: 'return $X == password;
'
- pattern: 'return password == $X;
'
- pattern: 'return $X == pass;
'
- pattern: 'return pass == $X;
'
- pattern: 'return $X == apiKey;
'
- pattern: 'return apiKey == $X;
'
- pattern: 'return $X == apiSecret;
'
- pattern: 'return apiSecret == $X;
'
- pattern: 'return $X == api_key;
'
- pattern: 'return api_key == $X;
'
- pattern: 'return $X == api_secret;
'
- pattern: 'return api_secret == $X;
'
- pattern: 'return $X == secret;
'
- pattern: 'return secret == $X;
'
- pattern: 'return $X == api;
'
- pattern: 'return api == $X;
'
- pattern: 'return $X !== auth_token;
'
- pattern: 'return auth_token !== $X;
'
- pattern: 'return $X !== token;
'
- pattern: 'return token !== $X;
'
- pattern: 'return $X !== hash;
'
- pattern: 'return hash !== $X;
'
- pattern: 'return $X !== password;
'
- pattern: 'return password !== $X;
'
- pattern: 'return $X !== pass;
'
- pattern: 'return pass !== $X;
'
- pattern: 'return $X !== apiKey;
'
- pattern: 'return apiKey !== $X;
'
- pattern: 'return $X !== apiSecret;
'
- pattern: 'return apiSecret !== $X;
'
- pattern: 'return $X !== api_key;
'
- pattern: 'return api_key !== $X;
'
- pattern: 'return $X !== api_secret;
'
- pattern: 'return api_secret !== $X;
'
- pattern: 'return $X !== secret;
'
- pattern: 'return secret !== $X;
'
- pattern: 'return $X !== api;
'
- pattern: 'return api !== $X;
'
- pattern: 'return $X != auth_token;
'
- pattern: 'return auth_token != $X;
'
- pattern: 'return $X != token;
'
- pattern: 'return token != $X;
'
- pattern: 'return $X != hash;
'
- pattern: 'return hash != $X;
'
- pattern: 'return $X != password;
'
- pattern: 'return password != $X;
'
- pattern: 'return $X != pass;
'
- pattern: 'return pass != $X;
'
- pattern: 'return $X != apiKey;
'
- pattern: 'return apiKey != $X;
'
- pattern: 'return $X != apiSecret;
'
- pattern: 'return apiSecret != $X;
'
- pattern: 'return $X != api_key;
'
- pattern: 'return api_key != $X;
'
- pattern: 'return $X != api_secret;
'
- pattern: 'return api_secret != $X;
'
- pattern: 'return $X != secret;
'
- pattern: 'return secret != $X;
'
- pattern: 'return $X != api;
'
- pattern: 'return api != $X;
'
message: '''String comparisons using ''''==='''', ''''!=='''', ''''!='''' and ''''==''''
is vulnerable to timing attacks. More info: https://snyk.io/blog/node-js-timing-attack-ccc-ctf/''
'
languages:
- javascript
severity: WARNING
metadata:
cwe: CWE-208
shortDescription: Observable timing discrepancy
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
- id: rules_lgpl_javascript_crypto_rule-node-aes-ecb
patterns:
- pattern-either:
- pattern: '$X.createCipheriv("=~/^aes-([0-9]+)-ecb$/i", ...)
'
- pattern: '$X.createDecipheriv("=~/^aes-([0-9]+)-ecb$/i", ...)
'
message: 'AES with ECB mode is deterministic in nature and not suitable for encrypting
large amount of repetitive data.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-327
shortDescription: Use of a broken or risky cryptographic algorithm
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_crypto_rule-node-insecure-random-generator
pattern-either:
- patterns:
- pattern-inside: 'require(''crypto'')
...
'
- pattern: '$X.pseudoRandomBytes(...)
'
- pattern: 'Math.random(...)
'
message: "This rule identifies use of cryptographically weak random number generators.\n\
Using cryptographically weak random number generators like `crypto.pseudoRandomBytes()`\
\ \nand `Math.random()` for security-critical tasks can expose systems to significant\
\ \nvulnerabilities. Attackers might predict the generated random numbers, compromising\
\ \nthe integrity and confidentiality of cryptographic operations. This could\
\ lead to \nbreaches where sensitive data is accessed or manipulated, authentication\
\ mechanisms \nare bypassed, or secure communications are intercepted, ultimately\
\ undermining the \nsecurity of the entire system or application.\n\nMitigation\
\ strategy:\nReplace the use of these cryptographically weak random number generators\
\ with \n`crypto.randomBytes()`, a method provided by Node.js's `crypto` module\
\ that \ngenerates cryptographically secure random numbers. This method should\
\ be used \nfor all operations requiring secure randomness, such as generating\
\ keys, tokens, \nor any cryptographic material.\n\nSecure Code Example:\n```\n\
const crypto = require('crypto');\nconst secureBytes = crypto.randomBytes(256);\n\
console.log(`Secure random bytes: ${secureBytes.toString('hex')}`);\n```\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-338
shortDescription: Use of cryptographically weak pseudo-random number generator
(PRNG)
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_crypto_rule-node-sha1
pattern-either:
- patterns:
- pattern-either:
- patterns:
- pattern-inside: '$Y = $X.createHash(''sha1'')
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.createHash(''sha1'').update("...")
'
- patterns:
- pattern-inside: 'require(''crypto-js'')
...
'
- pattern: '$X.SHA1("...")
'
- patterns:
- pattern-either:
- pattern-inside: '$M = require(''sha1'')
...
'
- pattern-inside: '$M = require(''js-sha1'')
...
'
- pattern: '$M("...")
'
- patterns:
- pattern-inside: 'require(''node-forge'')
...
'
- pattern-either:
- patterns:
- pattern-inside: '$Y = $X.md.sha1.create()
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.md.sha1.create().update("...")
'
- patterns:
- pattern-inside: '$X = require(''jshashes'')
...
$Y = new $X.SHA1()
...
'
- pattern: '$Y.$METHOD("...")
'
- patterns:
- pattern-inside: 'require(''hash.js'')
...
'
- pattern-either:
- patterns:
- pattern-inside: '$Y = $X.sha1()
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.sha1().update("...")
'
- patterns:
- pattern-inside: '$X = require(''jssha'')
...
'
- pattern-either:
- pattern: 'new $X(''SHA-1'', ...).update("...")
'
- patterns:
- pattern-inside: '$Y = new $X(''SHA-1'', ...)
...
'
- pattern: '$Y.update("...")
'
- patterns:
- pattern-either:
- pattern: '$X(''sha1'').update("...")
'
- patterns:
- pattern-inside: '$Y = $X(''sha1'')
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.subtle.digest(''SHA-1'', ...)
'
- patterns:
- pattern-either:
- pattern: '$X.SHA1.digest(...)
'
- patterns:
- pattern-inside: '$Y = $X.SHA1
...
'
- pattern: "$Y.digest(...) \n"
- patterns:
- pattern-either:
- pattern: '$X.codec.hex.fromBits($SJCL)
'
- patterns:
- pattern-inside: '$Y = $SJCL
...
'
- pattern: '$X.codec.hex.fromBits($Y)
'
- metavariable-pattern:
metavariable: $SJCL
pattern: '$K.hash.sha1.hash("...")
'
message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic\
\ applications due to its vulnerability to collision attacks,\nwhere two different\
\ inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks\
\ undermines the security of\ncryptographic operations, allowing attackers to\
\ forge signatures or\nmanipulate data without detection. This poses significant\
\ risks in\nauthentication systems, data integrity validations, and secure\ncommunications.\
\ \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \n\
algorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3.\
\ These algorithms offer significantly improved security and \nare resistant\
\ to collision attacks, making them suitable for cryptographic \npurposes in\
\ modern applications.\n\nSecure Code example: \n``` \nconst crypto = require('crypto');\
\ \nconst hash = crypto.createHash('sha256').update('sensitive data').digest('hex');\
\ \nconsole.log(hash); \n```\n"
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Use of weak hash
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-328
security-severity: MEDIUM
- id: rules_lgpl_javascript_crypto_rule-node-md5
pattern-either:
- patterns:
- pattern-either:
- patterns:
- pattern-inside: '$Y = $X.createHash(''md5'')
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.createHash(''md5'').update("...")
'
- patterns:
- pattern-inside: 'require(''crypto-js'')
...
'
- pattern: '$X.MD5("...")
'
- patterns:
- pattern-either:
- pattern-inside: '$M = require(''md5'')
...
'
- pattern-inside: '$M = require(''blueimp-md5'')
...
'
- pattern-inside: '$M = require(''js-md5'')
...
'
- pattern: '$M("...")
'
- patterns:
- pattern-inside: 'require(''node-forge'')
...
'
- pattern-either:
- patterns:
- pattern-inside: '$Y = $X.md.md5.create()
...
'
- pattern: '$Y.update("...")
'
- pattern: '$X.md.md5.create().update("...")
'
- patterns:
- pattern-inside: '$X = require(''jshashes'')
...
$Y = new $X.MD5()
...
'
- pattern: '$Y.$METHOD("...")
'
- patterns:
- pattern-either:
- patterns:
- pattern-inside: '$X = require(''create-hash'')
...
$Y = $X(''md5'')
...
'
- pattern: '$Y.update("...")
'
- patterns:
- pattern-inside: '$X = require(''create-hash'')
...
'
- pattern: "$X('md5').update(\"...\") \n"
message: "The MD5 hashing algorithm is considered cryptographically weak and \n\
vulnerable to collision attacks, where two different inputs generate \nthe same\
\ output hash. When used for hashing sensitive data, attackers \ncan exploit this\
\ weakness to generate collisions, allowing them to bypass \nsecurity checks or\
\ masquerade malicious data as legitimate. This \nvulnerability is particularly\
\ critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates,\
\ and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability,\
\ replace the MD5 hashing algorithm with \nstronger cryptographic hash functions,\
\ such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security\
\ and are resistant to \ncollision attacks, making them suitable for cryptographic\
\ purposes in \nmodern applications.\n\nSecure Code example :\n```\nconst crypto\
\ = require('crypto');\nconst hash = crypto.createHash('sha256').update('sensitive\
\ data').digest('hex');\nconsole.log(hash); \n```\n"
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Use of weak hash
category: security
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-328
security-severity: MEDIUM
- id: rules_lgpl_javascript_dos_rule-layer7-object-dos
mode: taint
pattern-sources:
- patterns:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern: $REQ.$FUNC. ...
- metavariable-regex:
metavariable: $FUNC
regex: ^(body|params|query|baseUrl|cookies|hostname|subdomains|ip|ips|originalUrl|path)$
pattern-sanitizers:
- patterns:
- pattern: $OBJ.slice($X, $Y)
- pattern-not: $OBJ.slice($X)
- pattern-not: $OBJ.slice(..., $OBJ.length)
- pattern-not: $OBJ.slice(..., Object.keys($OBJ).length)
pattern-sinks:
- patterns:
- pattern: 'for(...; $COND; ...){...}
'
- focus-metavariable: $COND
- metavariable-pattern:
metavariable: $COND
pattern-either:
- pattern: 'Object.Keys($VAR).length
'
- pattern: $VAR.length
- patterns:
- pattern-either:
- pattern: $OBJ.forEach
- pattern: $OBJ.map
- pattern: Object.keys($OBJ).map
- pattern: $OBJ.filter
- pattern: $OBJ.reduce
- pattern: $OBJ.reduceRight
- focus-metavariable: $OBJ
message: "This application is looping over user controlled objects, which can lead\
\ to a layer 7 denial of service vulnerability.\n\nA layer 7 denial of service\
\ attack refers to overloading the application layer of the OSI model, typically\
\ layer 7. \nThis can happen when user-controlled input such as objects, arrays,\
\ strings, etc. are iterated or looped over without proper validation or limits\
\ in place.\n\nFor example, if a user can control the size of an array or object\
\ passed into the application, \nthey could create an extremely large input that\
\ gets looped over. This would consume excessive CPU cycles or memory, \npotentially\
\ crashing or slowing down the application.\n\nTo prevent this, limits should\
\ be set on the number of iterations, input sizes, recursion depth, etc.\n\nSample\
\ case of secure array looped over with user-controlled input\n```\n// Potential\
\ DoS if req.body.list.length is large.\napp.post('/dos/layer7-object-dos/for-loop/1',\
\ function (req, res) {\n var list = req.body.list;\n for (let i = 0; i\
\ <= 10; i++) {\n if(!list[i]){\n // return;\n } \n \
\ }\n res.send(\"res\")\n});\n```\n\nImplementing protections against layer\
\ 7 denial of service attacks is important for securing modern web applications\
\ and APIs.\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-606
shortDescription: Unchecked input for loop condition
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_dos_rule-regex-dos
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$REGEX.test(<... $REQ ...>)
'
- pattern: '$REGEX.test(<... $REQ.$QUERY ...>)
'
- pattern: '$REGEX.test(<... $REQ.$BODY.$PARAM ...>)
'
- pattern: '$INP = <... $REQ ...>;
...
$REGEX.test(<... $INP ...>)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$REGEX.test(<... $INP ...>)
'
- pattern: '$INP = <... $REQ.$BODY.$PARAM ...>;
...
$REGEX.test(<... $INP ...>)
'
- pattern: '/.../g.exec(<... $REQ ...>)
'
- pattern: '/.../g.exec(<... $REQ.$QUERY ...>)
'
- pattern: '/.../.exec(<... $REQ.$BODY.$PARAM ...>)
'
- pattern: '$INP = <... $REQ ...>;
...
/.../.exec(<... $INP ...>)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
/.../.exec(<... $INP ...>)
'
- pattern: '$INP = <... $REQ.$BODY.$PARAM ...>;
...
/.../.exec(<... $INP ...>)
'
- pattern: '$RE = /.../;
...
$RE.exec(<... $REQ ...>)
'
- pattern: '$RE = /.../;
...
$RE.exec(<... $REQ.$QUERY ...>)
'
- pattern: '$RE = /.../;
...
$RE.exec(<... $REQ.$BODY.$PARAM ...>)
'
message: 'Ensure that the regex used to compare with user supplied input is safe
from regular expression denial of service.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-185
shortDescription: Incorrect regular expression
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_xss_rule-handlebars-noescape
mode: taint
pattern-sources:
- patterns:
- focus-metavariable: $REQ
- pattern: function ($REQ, $RES, ...) {...}
- pattern-either:
- pattern-inside: '$HB = require(''handlebars'');
...
'
- pattern-inside: 'import $HB from "handlebars";
'
pattern-sinks:
- pattern: '$HB.compile(..., {noEscape: true,...}, ...)(...)'
- pattern: 'var $METHOD = $HB.compile(..., {noEscape: true,...}, ...)
...
$METHOD(...)
'
message: "This application is compiling strings with `Handlebars.compile` using\
\ an insecure\noption of `{noEscape: true}`. This configuration bypasses the default\
\ behavior of \nHandlebars, which is to escape input values to prevent Cross-Site\
\ Scripting (XSS) \nattacks. \nXSS attacks are a type of security breach that\
\ occurs when an attacker manages to \ninject malicious scripts into web pages\
\ viewed by other users. These scripts can then \nexecute in the context of the\
\ victim's session, allowing the attacker to bypass access \ncontrols and potentially\
\ access sensitive information or perform actions on behalf of the \nuser.\
\ It is important to encode the data depending on the specific context it is used\
\ in. \n\nBy default, `Handlebars.compile` escapes input values to prevent XSS\
\ attacks. \nConsider using `Handlebars.compile` with default settings or set\
\ `{noEscape: false}` \nto force encoding of input data.\n\nExample of using Handlebars.compile\
\ safely:\n```\nvar template = \"This is {{target}}\";\nvar out = Handlebars.compile(template)({target:\
\ req.query.message});\nres.send(out);\n``` \n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
shortDescription: Improper neutralization of script-related HTML tags in a web
page (basic XSS)
cwe: CWE-80
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_xss_rule-xss-disable-mustache-escape
pattern: $OBJ.escapeMarkup = false
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
cwe: CWE-116
shortDescription: Improper encoding or escaping of output
security-severity: MEDIUM
category: security
message: 'Markup escaping disabled. This can be used with some template engines
to escape disabling of HTML entities, which can lead to XSS attacks.
'
- id: rules_lgpl_javascript_xss_rule-handlebars-safestring
mode: taint
pattern-sources:
- patterns:
- focus-metavariable: $REQ
- pattern: function ($REQ, $RES, ...) {...}
pattern-sinks:
- pattern-either:
- patterns:
- pattern-inside: '$HB = require(''handlebars'')
...
'
- pattern: new $HB.SafeString(...)
- patterns:
- pattern-inside: 'import $HB from "handlebars";
...
'
- pattern: new $HB.SafeString(...)
pattern-sanitizers:
- pattern-either:
- patterns:
- pattern-inside: '$HB = require(''handlebars'')
...
'
- pattern: $HB.escapeExpression(...)
- patterns:
- pattern-inside: 'import $HB from "handlebars";
...
'
- pattern: $HB.escapeExpression(...)
message: "This application is using a vulnerable method `Handlebars.SafeString(...)`.\n\
Handlebars SafeString method does not escape the data passed through it. \nUntrusted\
\ user input passing through SafeString method can make the application \nvulnerable\
\ to Cross-Site Scripting (XSS) attacks.\n\nXSS attacks are a type of security\
\ breach that occurs when an attacker manages to \ninject malicious scripts into\
\ web pages viewed by other users. These scripts can then \nexecute in the context\
\ of the victim's session, allowing the attacker to bypass access \ncontrols and\
\ potentially access sensitive information or perform actions on behalf of the\
\ \nuser. It is important to encode the data depending on the specific context\
\ it is used in. \n\nConsider using the `Handlebars.escapeExpression` method to\
\ escape user input while \nconstructing SafeString to avoid potential security\
\ concerns. Following is a secure code \nexample.\n```\n var returnObj = new\
\ Handlebars.SafeString(\"<h1>Handlebars safe string</h1>\" + Handlebars.escapeExpression(req.query.message))\n\
\ res.send(returnObj.string)\n```\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
cwe: CWE-79
shortDescription: Improper neutralization of input during web page generation
(Cross-site Scripting)
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_xss_rule-express-xss
mode: taint
options:
taint_unify_mvars: true
pattern-sources:
- patterns:
- patterns:
- metavariable-regex:
metavariable: $LIB
regex: (?<!\s)\bexpress(?:\/.*)?\b
- pattern-either:
- pattern-inside: 'import { ... } from ''$LIB''
...
'
- pattern-inside: 'import $IMPORT from ''$LIB''
...
'
- pattern-inside: 'require(''$LIB'')
...
'
- pattern-either:
- patterns:
- focus-metavariable: $REQ
- pattern: function ($REQ, $RES, ...) {...}
- patterns:
- focus-metavariable: $REQ
- pattern: function $FUNC($REQ, $RES, ...) {...}
pattern-propagators:
- pattern: $ARR.push($IN)
from: $IN
to: $ARR
pattern-sanitizers:
- pattern: encodeURI(...)
- pattern: encodeURIComponent(...)
pattern-sinks:
- patterns:
- focus-metavariable: $INPUT
- pattern-either:
- pattern: $RES. ... .send($INPUT)
- pattern: $RES. ... .write($INPUT)
message: "This application accepts user input directly from the client side without\
\ validation. \nThis could lead to Cross Site Scripting (XSS) if the input contains\
\ malicious script code and \nthe application server does not properly escape\
\ or sanitize the output. \nConsider encoding input data before sending it to\
\ the client side. \n\n```\n// safe method of sending user input data\nrouter.get('/safe/1',\
\ (req, res) => {\n var name = encodeURI(req.query.name); \n res.send(name);\n\
})\n```\n\nXSS is an attack that exploits a web application or system to treat\
\ user input as markup or script code. \nIt is important to encode the data depending\
\ on the specific context in which it is used. \n"
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
- id: rules_lgpl_javascript_xss_rule-xss-serialize-javascript
pattern-either:
- patterns:
- pattern-inside: '$S = require(''serialize-javascript'')
...
'
- pattern: '$S(..., {...,unsafe: true,...})'
- patterns:
- pattern-inside: 'import serialize from "serialize-javascript";
...
'
- pattern: 'serialize(..., {...,unsafe: true,...})'
message: "This application is serializing Javascript objects with vulnerable \n\
configurations by setting `{unsafe: true}` in serialize-javascript. \n\nThis could\
\ lead to Cross Site Scripting (XSS) if the input was malicious \nscript code\
\ and the application server is not properly validating the output.\n\n```\n//\
\ safe use of serialize-javascript\nconst jsObj = serialize({\n foo: htmlResponse\n\
\ }\n);\n```\n\nXSS is an attack which exploits a web application or system to\
\ treat user input as markup or script code. \nIt is important to encode the data\
\ depending on the specific context it is used in. \n\nBy default, serialize-javascript\
\ encodes input values to prevent XSS attacks. \nConsider using serialize-javascript\
\ with default settings or set `{unsafe: false}` to encode\ninput data.\n"
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
shortDescription: Improper neutralization of script-related HTML tags in a web
page (basic XSS)
cwe: CWE-80
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_xss_rule-squirrelly-autoescape
pattern-either:
- patterns:
- pattern-inside: '$SQLY = require(''squirrelly'')
...
'
- pattern: $SQLY.autoEscaping(false)
- patterns:
- pattern-inside: 'import $SQLY from ''squirrelly'';
...
'
- pattern: $SQLY.autoEscaping(false)
message: "This application is rendering HTML with vulnerable \nconfigurations by\
\ setting Sqrl.autoEscaping(false) in squirrelly.\n\nThis could lead to Cross\
\ Site Scripting (XSS) if the input is malicious \nscript code and the application\
\ server is not properly validating the output.\n\n```\n// safe use of squirrelly\
\ render\nvar myTemplate = \"<p>My Message is: {{message}}</p>\"\nSqrl.Render(myTemplate,\
\ {message: req.query.message})\n```\n\nXSS is an attack that exploits a web application\
\ or system to treat user input as markup or script code. \nIt is important to\
\ encode the data depending on the specific context it is used in.\n\nBy default,\
\ squirrelly autoEscaping(true) escapes input values to prevent XSS attacks. \n\
Consider using squirrelly with default autoEscaping settings.\n"
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
security-severity: MEDIUM
- id: rules_lgpl_javascript_xml_rule-node-entity-expansion
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$PARSER = new expat.Parser()
...
$PARSER.write(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$PARSER = new expat.Parser()
...
$PARSER.write(..., <... $REQ.$QUERY.$FOO ...>, ...)
'
- pattern: '$PARSER = new expat.Parser()
...
$PARSER.write(..., <... $REQ.$QUERY.$FOO.$FILE ...>, ...)
'
message: 'User controlled data in XML Parsers can result in XML Internal Entity
Processing vulnerabilities like in DoS.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
cwe: CWE-776
shortDescription: Improper restriction of recursive entity references in DTDs
(XML Entity Expansion)
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_xml_rule-xxe-expat
patterns:
- pattern-inside: 'require(''node-expat'')
...
'
- pattern-either:
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern-inside: '$PARSER = new $EXPAT.Parser(...)
...
'
- pattern-inside: '$PARSER = new Parser(...)
...
'
- pattern-either:
- pattern: $PARSER.parse(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PARSER.parse(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PARSER.parse(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PARSER.parse(<... $INPUT ...>,...)
'
- pattern: $PARSER.write(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $PARSER.write(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PARSER.write(<... $INPUT ...>,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$PARSER.write(<... $INPUT ...>,...)'
message: 'Make sure that unverified user data can not reach the XML Parser, as it
can result in XML External or Internal Entity (XXE) Processing vulnerabilities.
'
metadata:
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
- id: rules_lgpl_javascript_xml_rule-node-xpath-injection
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: 'function ($REQ, $RES, ...) {...}
'
- pattern: 'function $FUNC($REQ, $RES, ...) {...}
'
- focus-metavariable: $REQ
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: '$XPATH = require(''xpath'')
...
'
- pattern-inside: 'import { $XPATH } from ''xpath''
...
'
- pattern-inside: 'import { $K as $XPATH } from ''xpath''
...
'
- pattern: "$XPATH.parse($REQ, ...) \n"
- focus-metavariable: $REQ
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n...\n$XPATH.parse($REQ, ...) \n...\n} \n"
- pattern: "$A = $VALIDATION\n...\nif($A){\n...\n$XPATH.parse($REQ, ...) \n\
...\n}\n"
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.includes(...) \n"
- pattern: '$AL.indexOf(...) !== -1
'
- pattern: '$AL.find(...) !== undefined
'
- pattern: '$ALS.has(...)
'
message: "Passing untrusted user input in `xpath.parse()` can result in XPATH injection\n\
vulnerability. This could be abused by malicious actors to execute expressions\
\ on\non XML files to capture unauthorized information.\nTo prevent XPATH injection\
\ vulnerabilities:\n\n- Always validate and sanitize user inputs, especially parameters\n\
or query strings that may influence the flow of the application.\n- Avoid directly\
\ using user input for parsing. If unavoidable, ensure\nstrict validation against\
\ an allowlist. \n- Use allowlists (lists of permitted expressions) to validate\
\ user input \nagainst known, trusted expressions before performing the parse.\n\
\n\nFollowing is an example of secure validation against allowlist to prevent\
\ the vulnerability:\n```\n// Define a list of explicitly allowed expressions\
\ for parsing\nconst allowedExpr = [\n 'expression1',\n 'expression2',\n\
\ 'expression3'\n];\n\napp.get('/xml/xpath/1', (req, res) => {\n var expression\
\ = req.params.exp;\n var isAllowed = allowedExpr.includes(expression);\n \
\ let xml_string = fs.readFileSync(\"books.xml\", \"utf8\");\n var doc =\
\ new dom().parseFromString(xml_string, 'text/xml');\n if (isAllowed) {\n \
\ // If the expression is allowed, proceed with the parsing\n var\
\ evaluator = xpath.parse(\"//\"+expression);\n var nodes = evaluator.select({\
\ node: doc }); \n res.send(nodes[0].firstChild.data);\n \
\ } else {\n res.status(400).send('Invalid expression');\n }\n});\n\
```\n"
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-643
shortDescription: Improper neutralization of data within XPath expressions (XPath
Injection)
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_xml_rule-node-xxe
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...)
'
- pattern: '$LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$LIBXML.parseXmlString(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXmlString(...,
<... $FOO ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXmlString(...,
<... $FOO ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY ...>; ... $LIBXML.parseXmlString(..., <...
$FOO ...>, ...)
'
- pattern: '$LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...)
'
- pattern: '$LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$LIBXML.parseXml(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXml(...,
<... $FOO ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXml(..., <...
$FOO ...>, ...)
'
- pattern: '$FOO = <... $REQ.$QUERY ...>;
...
$LIBXML.parseXml(..., <... $FOO ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$PARSER.parseString(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$PARSER.parseString(..., <... $REQ.$QUERY.$BAR ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$PARSER.parseString(..., <... $REQ.$QUERY.$BAR.$FILE ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$PARSER.push(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$PARSER.push(..., <... $REQ.$QUERY.$FOO ...> , ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$PARSER.push(..., <... $REQ.$QUERY.$FOO.$FILE ...> , ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$FOO = <... $REQ.$QUERY ...>;
...
$PARSER.parseString(..., <... $FOO ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$FOO = <... $REQ.$QUERY.$BAR ...>;
...
$PARSER.parseString(..., <... $FOO ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxParser()
...
$FOO = <... $REQ.$QUERY.$BAR.$FILE ...>;
...
$PARSER.parseString(..., <... $FOO ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$FOO = <... $REQ.$QUERY ...>;
...
$PARSER.push(..., <... $FOO ...>, ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$FOO = <... $REQ.$QUERY.$BAR ...>;
...
$PARSER.push(..., <... $FOO ...> , ...)
'
- pattern: '$PARSER = new libxmljs.SaxPushParser()
...
$FOO = <... $REQ.$QUERY.$BAR.$FILE ...>;
...
$PARSER.push(..., <... $FOO ...> , ...)
'
message: 'User controlled data in XML parsers can result in XML External or Internal
Entity (XXE) Processing vulnerabilities
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_headers_rule-generic-cors
patterns:
- pattern: '$APP.options(''*'', cors(...))
'
message: 'Access-Control-Allow-Origin response header is set to "*". This will disable
CORS Same Origin Policy restrictions.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-346
shortDescription: Origin validation error
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-helmet-feature-disabled
patterns:
- pattern-either:
- pattern: '$HELMET(..., {frameguard: false}, ...)
'
- pattern: '$HELMET(..., {contentSecurityPolicy: false}, ...)
'
- pattern: '$HELMET(..., {permittedCrossDomainPolicies: false}, ...)
'
- pattern: '$HELMET(..., {dnsPrefetchControl: false}, ...)
'
- pattern: '$HELMET(..., {expectCt: false}, ...)
'
- pattern: '$HELMET(..., {featurePolicy: false}, ...)
'
- pattern: '$HELMET(..., {hsts: false}, ...)
'
- pattern: '$HELMET(..., {ieNoOpen: false}, ...)
'
- pattern: '$HELMET(..., {noSniff: false}, ...)
'
- pattern: '$HELMET(..., {hidePoweredBy: false}, ...)
'
- pattern: '$HELMET(..., {referrerPolicy: false}, ...)
'
- pattern: '$HELMET(..., {xssFilter: false}, ...)
'
message: 'One or more Security Response header is explicitly disabled in Helmet.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-358
shortDescription: Improperly implemented security check for standard
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-domain
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...)
- pattern-not-inside: '$OPTS = <... {cookie:{domain:...}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {domain:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {domain:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.domain = ...;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.domain = ...;
...
$SESSION($OPTS,...)
'
message: '''Default session middleware settings: `domain` not set. It indicates
the domain of the cookie; use it to compare against the domain of the server in
which the URL is being requested. If they match, then check the path attribute
next.''
'
severity: INFO
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: INFO
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-samesite
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{sameSite:true}} ...>,...)
- pattern-not-inside: $SESSION(<... {cookie:{sameSite:'lax'}} ...>,...)
- pattern-not-inside: $SESSION(<... {cookie:{sameSite:'strict'}} ...>,...)
- pattern-not-inside: '$OPTS = <... {cookie:{sameSite:true}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {sameSite:true} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {sameSite:true} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.sameSite = true;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.sameSite = true;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = <... {cookie:{sameSite:''strict''}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {sameSite:''strict''} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {sameSite:''strict''} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.sameSite = ''strict'';
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.sameSite = ''strict'';
...
$SESSION($OPTS,...)
'
message: '''Default session middleware settings: `sameSite` attribute is not configured
to strict or lax. These configurations provides protection against Cross Site
Request Forgery attacks.''
'
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-1275
shortDescription: Sensitive cookie with improper SameSite attribute
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-header-xss-lusca
patterns:
- pattern-inside: '$X = require(''lusca'')
...
'
- pattern-not: '$X.use(helmet())
'
- pattern-either:
- pattern: '$X.xssProtection(false)
'
- pattern: '$X({ xssProtection: false})
'
message: 'X-XSS-Protection header is set to 0. This will disable the browser''s
XSS Filter.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-358
shortDescription: Improperly implemented security check for standard
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-header-xss-generic
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$RES.header("=~/x-xss-protection/i", 0, ...)
'
- pattern: '$RES.set("=~/x-xss-protection/i", 0, ...)
'
- pattern: '$RES.set(..., { "=~/x-xss-protection/i" : 0 }, ...)
'
- pattern: '$RES.writeHead(..., {"=~/x-xss-protection/i": 0 }, ...)
'
message: 'X-XSS-Protection header is set to 0. This will disable the browser''s
XSS Filter.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-358
shortDescription: Improperly implemented security check for standard
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-path
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...)
- pattern-not-inside: '$OPTS = <... {cookie:{path:...}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {path:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {path:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.path = ...;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.path = ...;
...
$SESSION($OPTS,...)
'
message: '''Default session middleware settings: `path` not set. It indicates the
path of the cookie; use it to compare against the request path. If this and domain
match, then send the cookie in the request.''
'
severity: INFO
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: INFO
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-secure
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...)
- pattern-not-inside: '$OPTS = <... {cookie:{secure:true}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {secure:true} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {secure:true} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.secure = true;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.secure = true;
...
$SESSION($OPTS,...)
'
message: '''Default session middleware settings: `secure` not set. It ensures the
browser only sends the cookie over HTTPS.''
'
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-614
shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-maxage
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {cookie:{maxAge:...}} ...>,...)
- pattern-not-inside: '$OPTS = <... {cookie:{maxAge:...}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE = <... {maxAge:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {maxAge:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$COOKIE.maxAge = ...;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.cookie.maxAge = ...;
...
$SESSION($OPTS,...)'
message: '''Session middleware settings: `maxAge` not set. Use it to set expiration
date for cookies.''
'
severity: INFO
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-613
shortDescription: Insufficient session expiration
security-severity: INFO
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-default
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern: $SESSION(...)
- pattern-not-inside: $SESSION(<... {name:...} ...>,...)
- pattern-not-inside: '$OPTS = <... {name:...} ...>;
...
$SESSION($OPTS,...)
'
- pattern-not-inside: '$OPTS = ...;
...
$OPTS.name = ...;
...
$SESSION($OPTS,...)
'
message: 'Consider changing the default session cookie name. An attacker can use
it to fingerprint the server and target attacks accordingly.
'
severity: INFO
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-522
shortDescription: Insufficiently protected credentials
security-severity: INFO
category: security
- id: rules_lgpl_javascript_headers_rule-cookie-session-no-httponly
patterns:
- pattern-either:
- pattern-inside: '$SESSION = require(''cookie-session'')
...
'
- pattern-inside: '$SESSION = require(''express-session'')
...
'
- pattern-either:
- pattern-inside: $SESSION(<... {cookie:{httpOnly:false}} ...>,...)
- pattern-inside: '$OPTS = <... {cookie:{httpOnly:false}} ...>;
...
$SESSION($OPTS,...)
'
- pattern-inside: '$OPTS = ...;
...
$COOKIE = <... {httpOnly:false} ...>;
...
$SESSION($OPTS,...)
'
- pattern-inside: '$OPTS = ...;
...
$OPTS.cookie = <... {httpOnly:false} ...>;
...
$SESSION($OPTS,...)
'
- pattern-inside: '$OPTS = ...;
...
$COOKIE.httpOnly = false;
...
$SESSION($OPTS,...)
'
- pattern-inside: '$OPTS = ...;
...
$OPTS.cookie.httpOnly = false;
...
$SESSION($OPTS,...)
'
message: '''Session middleware settings: `httpOnly` is explicitly set to false. It
ensures that sensitive cookies cannot be accessed by client side JavaScript and
helps to protect against cross-site scripting attacks.''
'
severity: WARNING
languages:
- javascript
metadata:
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
cwe: CWE-1004
shortDescription: Sensitive cookie without 'HttpOnly' flag
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-express-cors
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$APP.options(''*'', cors(...))
'
- pattern: '$RES.set("=~/access-control-allow-origin/i", ''*'', ...)
'
- pattern: '$RES.set(..., { "=~/access-control-allow-origin/i" : ''*'' }, ...)
'
- pattern: '$RES.header("=~/access-control-allow-origin/i", ''*'', ...)
'
- pattern: '$RES.writeHead(..., {"=~/access-control-allow-origin/i": ''*'' },
...)
'
message: 'Access-Control-Allow-Origin response header is set to "*". This will disable
CORS Same Origin Policy restrictions.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-346
shortDescription: Origin validation error
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_headers_rule-generic-header-injection
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$INP = $REQ.$QUERY;
...
$RES.set(..., <... $INP ...>, ...)
'
- pattern: '$INP = $REQ.$QUERY.$VAR;
...
$RES.set(..., <... $INP ...>, ...)
'
- pattern: '$INP = $REQ.$VAR;
...
$RES.set(..., { $X: <... $INP ...>}, ...)
'
- pattern: '$INP = $REQ.$QUERY.$FOO;
...
$RES.set(..., { $X: <... $INP ...>}, ...)
'
- pattern: '$INP = $REQ.$VAR;
...
$RES.writeHead(..., { $X: <... $INP ...> }, ...)
'
- pattern: '$INP = $REQ.$QUERY.$FOO;
...
$RES.writeHead(..., { $X: <... $INP ...> }, ...)
'
- pattern: '$RES.set(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$RES.set(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$RES.set(..., { $X: <... $REQ.$VAR ...>}, ...)
'
- pattern: '$RES.set(..., { $X: <... $REQ.$QUERY.$FOO ...>}, ...)
'
- pattern: '$RES.writeHead(..., { $X: <... $REQ.$VAR ...> }, ...)
'
- pattern: '$RES.writeHead(..., { $X: <... $REQ.$QUERY.$FOO ...> }, ...)
'
message: 'Untrusted user input in response header will result in HTTP Header Injection
or Response Splitting Attacks.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-644
shortDescription: Improper neutralization of HTTP headers for scripting syntax
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_headers_rule-host-header-injection
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$X = <... "=~/.*http[s]*:///i" + $REQ.host ...>;
'
- pattern: '$X = <... "=~/.*http[s]*:///i" + $REQ["host"] ...>;
'
- pattern: '$X = <... "=~/.*http[s]*:///i" + $REQ("host") ...>;
'
- pattern: '$X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>};
'
- pattern: '$X = { $Y: <... "=~/.*http[s]*:///i" + $REQ["host"] ...>};
'
- pattern: '$X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>};
'
- pattern: '$Z = $REQ.host;
...
$X = <... "=~/.*http[s]*:///i" + $Z ...>;
'
- pattern: '$Z = $REQ["host"];
...
$X = <... "=~/.*http[s]*:///i" + $Z ...>;
'
- pattern: '$Z = $REQ("host")
...
$X = <... "=~/.*http[s]*:///i" + $Z ...>;
'
- pattern: '$Z = $REQ.host;
...
$X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>};
'
- pattern: '$Z = $REQ["host"];
...
$X = { $Y: <... "=~/.*http[s]*:///i" + $Z ...>};
'
- pattern: '$Z = $REQ("host")
...
$X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>};
'
message: 'Using untrusted Host header for generating dynamic URLs can result in
web cache and or password reset poisoning.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-348
shortDescription: Use of less trusted source
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_traversal_rule-admzip-path-overwrite
patterns:
- pattern-inside: '$X = require(''adm-zip'')
...
'
- pattern-not: 'if ($FILENAME.indexOf(''..''))
'
- pattern-not: '$FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME,
...)))
'
- pattern-not: '$FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...)))
'
- pattern-not: '$FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...)))
'
- pattern-either:
- pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.createWriteStream(...)
}, ...)
- pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFile(...) },
...)
- pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFileSync(...)
}, ...)
message: 'Insecure ZIP archive extraction using adm-zip can result in arbitrary
path over write and can result in code injection.
'
languages:
- javascript
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
category: security
severity: WARNING
- id: rules_lgpl_javascript_traversal_rule-join-resolve-path-traversal
patterns:
- pattern-inside: 'require(''path'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $PATH.join(...,<... $REQ.$BODY ...>,...)
- pattern: $PATH.join(...,<... $REQ.$QUERY.$FOO ...>,...)
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$PATH.join(...,<... $VAR ...>,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$PATH.join(...,<... $VAR ...>,...)
'
- pattern: $PATH.resolve(...,<... $REQ.$BODY ...>,...)
- pattern: $PATH.resolve(...,<... $REQ.$QUERY.$FOO ...>,...)
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$PATH.resolve(...,<... $VAR ...>,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$PATH.resolve(...,<... $VAR ...>,...)'
message: '''Path constructed with user input can result in Path Traversal. Ensure
that user input does not reach `join()` or `resolve()`. ''
'
languages:
- javascript
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
category: security
severity: WARNING
- id: rules_lgpl_javascript_traversal_rule-zip-path-overwrite
patterns:
- pattern-either:
- pattern-inside: 'import $X from ''unzipper''
...
'
- pattern-inside: '$X = require(''unzipper'')
...
'
- pattern-inside: "$Y.pipe($X.Parse(...)).on('entry', function $FUNC(...) {\n \
\ ...\n}, ...)\n"
- pattern-not-inside: "if (<... $FILENAME.indexOf(...) ...>){ \n...\n}\n"
- pattern-not-inside: '$BASE = $PATH.basename($FILENAME, ...)
...
$JOIN = $PATH.join(..., $BASE)
...
'
- pattern-not: '$FS.$MTD($PATH.join(..., $PATH.basename($FILENAME, ...)))
'
- pattern: '$FS.$MTD($FIL, ...)
'
- metavariable-regex:
metavariable: $MTD
regex: ^(writeFileSync|writeFile|createWriteStream)$
message: "This application is extracting ZIP archives without sanitizing paths or\
\ writing files to a dedicated extraction directory. \nThis allows attackers to\
\ overwrite sensitive files or inject malicious code by manipulating TAR archive\
\ contents.\n\nTo fix, sanitize all paths from ZIP archives before writing extracted\
\ files using path.basename and path.join.\n\nExample of extracting tar files\
\ safely:\n```\napp.get(\"/extract\", async (req, res) => {\n fs.createReadStream(zipPath)\n\
\ .pipe(unzipper.Parse())\n .on('entry', entry => {\n \
\ const directory = 'assets/tar/extracted/';\n const filename = entry.path;\n\
\ entry.pipe(fs.createWriteStream(path.join(directory, filename)));\n\
\ });\n});\n```\n\nWrite extracted files only to a dedicated extraction\
\ directory, not the global filesystem. Limit extracts to allowed file type.\n\
\nSee OWASP Path Traversal (https://owasp.org/www-community/attacks/Path_Traversal)\
\ and Unrestricted Upload of File with \nDangerous Type (https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload)\
\ for more details.\n"
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_traversal_rule-tar-path-overwrite
patterns:
- pattern-inside: '$X = require(''tar-stream'')
...
'
- pattern-not-inside: "$Y.pipe($UNZIP.Parse(...)).on('entry', function $FUNC(...)\
\ {\n ...\n}, ...)\n"
- pattern-inside: "$EXTRACT.on('entry', function $FUNC(...) {\n ...\n}, ...)\n"
- pattern-not: 'if ($FILENAME.indexOf(''..''))
'
- pattern-not: '$FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME,
...)))
'
- pattern-not: '$FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...)))
'
- pattern-not: '$FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...)))
'
- pattern-either:
- pattern: '$FS.createWriteStream($FIL, ...)
'
- pattern: '$FS.writeFile($FIL, ...)
'
- pattern: '$FS.writeFileSync($FIL, ...)
'
message: 'Insecure TAR archive extraction can result in arbitrary path over write
and can result in code injection.
'
languages:
- javascript
severity: WARNING
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_traversal_rule-generic-path-traversal
mode: taint
languages:
- javascript
pattern-sources:
- patterns:
- focus-metavariable: $REQ
- pattern: function ($REQ, $RES, ...) {...}
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: '$FS = require(''fs'')
...
'
- pattern-inside: 'import $FS from ''fs''
...
'
- pattern-either:
- pattern: $FS.createReadStream(...)
- patterns:
- pattern: $FS.readFile($REQ, ...)
- focus-metavariable: $REQ
- patterns:
- pattern: $FS.readFileSync($REQ,...)
- focus-metavariable: $REQ
- patterns:
- pattern: $FS.readFileAsync($REQ,...)
- focus-metavariable: $REQ
message: "This application is using untrusted user input with the readFile() and\n\
readFileSync() functions. \nThis can lead to directory traversal attacks, as reading\
\ files with untrusted input enables arbitrary file access.\nAn attacker could\
\ craft malicious input that traverses the file system and exposes sensitive files.\
\ \nPlease consider sanitizing and validating all user input before passing it\
\ to readFile() or readFileSync() to prevent unwanted file reads.\nHere is an\
\ example of a safer usage in readFileAsync():\n```\napp.get('/foo', function\
\ (req, res) {\n var fileName = config.dirName + '/' + data;\n fs.readFileAsync(\"\
fileName\")\n .then(function (data) {\n res.download(fileName,\
\ downloadFileName);\n })\n })\n```\nFor more details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n"
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-23
shortDescription: Relative path traversal
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_traversal_rule-express-lfr
mode: taint
pattern-sources:
- patterns:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern: $REQ.$FUNC. ...
- metavariable-regex:
metavariable: $FUNC
regex: ^(body|params|query|cookies|hostname|subdomains|ip|ips|originalUrl|path)$
pattern-sinks:
- pattern: $RES.render(..., $VAR)
message: "This application is using untrusted user input in express render() function.\n\
Rendering templates with untrusted user input enables arbitrary file read \nvulnerabilities\
\ when using templating engines like Handlebars (hbs). \n\nAn attacker can craft\
\ malicious input that traverses the filesystem and exposes sensitive files. \n\
Consider sanitizing and validating all user input before passing it to render()\
\ to prevent arbitrary file reads. \n\nSample safe use of express.render function\n\
```\napp.get(\"/traversal/2\", async (req, res) => {\n var indexPath = \"index\"\
;\n res.render(indexPath, { title: \"Index Page\" })\n});\n```\n\nFor more\
\ details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n"
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-23
shortDescription: Relative path traversal
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_traversal_rule-express-lfr-warning
patterns:
- pattern-not-inside: 'require(''hbs'')
...
'
- pattern-inside: 'require(''express'')
...
'
- pattern-either:
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$RES.render($VIEW, <... $INP ...>)
'
- pattern: '$INP = <... $REQ.$QUERY.$FOO ...>;
...
$RES.render($VIEW, <... $INP ...>)
'
- pattern: $RES.render($VIEW, <... $REQ.$QUERY.$FOO ...>)
- pattern: $RES.render($VIEW, <... $REQ.$BODY ...>)
message: 'Untrusted user input in express render() function can result in arbitrary
file read if hbs templating is used.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe: CWE-23
shortDescription: Relative path traversal
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_redirect_rule-express-open-redirect
mode: taint
pattern-sources:
- patterns:
- pattern-inside: 'function ($REQ, $RES, ...) {...}
'
- focus-metavariable: $REQ
pattern-sinks:
- pattern: '$RES.redirect(...)
'
pattern-sanitizers:
- pattern-either:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n ...\n $RES.redirect(...)\n ...\n} \n"
- pattern: "$A = $VALIDATION\n...\nif($A){\n ...\n $RES.redirect(...)\n\
\ ...\n}\n"
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.includes(...) \n"
- pattern: '$AL.indexOf(...) !== -1
'
- pattern: '$AL.find(...) !== undefined
'
- pattern: '$ALS.has(...)
'
- patterns:
- pattern: '$RES.redirect("$DOM" + ...)
'
- metavariable-regex:
metavariable: $DOM
regex: (http(s)?:\/\/.*\/)
message: "Passing untrusted user input in `redirect()` can result in an open redirect\n\
vulnerability. This could be abused by malicious actors to trick users into \n\
being redirected to websites under their control to capture authentication\ninformation.\
\ \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize\
\ user inputs, especially URL parameters\n or query strings that may influence\
\ the flow of the application.\n- Use allowlists (lists of permitted URLs) to\
\ validate redirect targets \n against known, trusted URLs before performing the\
\ redirect.\n- Avoid directly using user input for redirecting. If unavoidable,\
\ ensure\n strict validation against an allowlist.\n\nFollowing is an example\
\ of secure validation against allowlist to prevent the vulnerability:\n ```\n\
\ // Define a list of explicitly allowed URLs for redirection\n const allowedUrls\
\ = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n\
\ 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req,\
\ res) => {\n const url = decodeURIComponent(req.params.url);\n const\
\ isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If\
\ the URL is allowed, proceed with the redirect\n res.redirect(url);\n\
\ } else {\n res.status(400).send('Invalid redirect URL');\n }\n\
\ });\n ```\n"
languages:
- javascript
severity: ERROR
metadata:
shortDescription: URL redirection to untrusted site 'open redirect'
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-601
security-severity: CRITICAL
- id: rules_lgpl_javascript_redirect_rule-express-open-redirect2
mode: taint
pattern-sources:
- patterns:
- pattern-inside: 'function ($REQ, $RES, ...) {...}
'
- focus-metavariable: $REQ
pattern-sinks:
- pattern-either:
- patterns:
- pattern-not: '$RES.$METHOD("=~/location/i", "=~/http(s)?:\/\/.*\//" + ...)
'
- pattern-not-inside: '$VAR = "=~/http(s)?:\/\/.*\//" + ...;
...
'
- pattern: '$RES.$METHOD("=~/location/i", $VAR)
'
- metavariable-regex:
metavariable: $METHOD
regex: (header|set|append|setHeader)
- patterns:
- pattern-not-inside: '$V = "=~/http(s)?:\/\/.*\//" + ...;
...
'
- pattern-not:
patterns:
- pattern: "$RES.writeHead(..., { \n ..., \n location: $V,\n ...\n\
})\n"
- metavariable-pattern:
metavariable: $V
patterns:
- pattern: '"=~/http(s)?:\/\/.*\//" + ...
'
- pattern: "$RES.writeHead(..., { \n ..., \n location:\
\ $V,\n ...\n })\n"
- focus-metavariable: $V
- patterns:
- pattern-not: '$RES.location("=~/http(s)?:\/\/.*\//" + ...)
'
- pattern-not-inside: '$VAR = "=~/http(s)?:\/\/.*\//" + ...;
...
'
- pattern: '$RES.location($VAR)
'
pattern-sanitizers:
- pattern-either:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n ...\n} \n"
- pattern: "$A = $VALIDATION\n...\nif($A){\n ...\n}\n"
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.includes(...) \n"
- pattern: '$AL.indexOf(...) !== -1
'
- pattern: '$AL.find(...) !== undefined
'
- pattern: '$ALS.has(...)
'
message: "Passing untrusted user input in `redirect()` can result in an open redirect\n\
vulnerability. This could be abused by malicious actors to trick users into \n\
being redirected to websites under their control to capture authentication\ninformation.\
\ \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize\
\ user inputs, especially URL parameters\n or query strings that may influence\
\ the flow of the application.\n- Use allowlists (lists of permitted URLs) to\
\ validate redirect targets \n against known, trusted URLs before performing the\
\ redirect.\n- Avoid directly using user input for redirecting. If unavoidable,\
\ ensure\n strict validation against an allowlist.\n\nFollowing is an example\
\ of secure validation against allowlist to prevent the vulnerability:\n ```\n\
\ // Define a list of explicitly allowed URLs for redirection\n const allowedUrls\
\ = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n\
\ 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req,\
\ res) => {\n const url = decodeURIComponent(req.params.url);\n const\
\ isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If\
\ the URL is allowed, proceed with the redirect\n res.location(url).status(302).end();\n\
\ } else {\n res.status(400).send('Invalid redirect URL');\n }\n\
\ });\n ```\n"
languages:
- javascript
severity: ERROR
metadata:
shortDescription: URL redirection to untrusted site 'open redirect'
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-601
security-severity: CRITICAL
- id: javascript_exec_rule-child-process
message: "OS command injection is a critical vulnerability that can lead to a full\
\ system\ncompromise as it may allow an adversary to pass in arbitrary commands\
\ or arguments\nto be executed.\n\nUser input should never be used in constructing\
\ commands or command arguments\nto functions which execute OS commands. This\
\ includes filenames supplied by\nuser uploads or downloads.\n\nEnsure your application\
\ does not:\n\n- Use user-supplied information in the process name to execute.\n\
- Use user-supplied information in an OS command execution function which does\n\
not escape shell meta-characters.\n- Use user-supplied information in arguments\
\ to OS commands.\n\nThe application should have a hardcoded set of arguments\
\ that are to be passed\nto OS commands. If filenames are being passed to these\
\ functions, it is\nrecommended that a hash of the filename be used instead, or\
\ some other unique\nidentifier. It is strongly recommended that a native library\
\ that implements\nthe same functionality be used instead of using OS system commands,\
\ due to the\nrisk of unknown attacks against third-party commands.\n\nWhen specifying\
\ the OS command, ensure the application uses the full path\ninformation, otherwise\
\ the OS may attempt to look up which process to execute\nand could be vulnerable\
\ to untrusted search path vulnerabilities (CWE-426).\n\nExample of safely executing\
\ an OS command:\n```\nconst child_process = require('child_process');\nconst\
\ fs = require('fs');\nconst crypto = require('node:crypto');\nconst { mkdtempSync\
\ } = require('node:fs');\n\nfunction executeCommand(userFileData) {\n // Create\
\ a temporary directory, preferably in an application directory\n // that only\
\ the application has access to.\n const fileDir = mkdtempSync('/tmp/tmpdir-');\n\
\ // Generate a random filename, do not use user input\n const filePath\
\ = fileDir + path.sep + crypto.randomUUID();\n // Write the user-supplied\
\ data to the temporary file.\n fs.writeFileSync(filePath, userFileData);\n\
\ // Execute a program with a hardcoded path to the binary\n child_process.exec(`/bin/cat\
\ ${filePath}`, (error, stdout, stderr) => {\n // Delete the temporary\
\ directory and file if no longer needed\n fs.rmSync(fileDir, { recursive:\
\ true, force: true });\n if (error) {\n console.error(`exec error:\
\ ${error}`);\n return;\n }\n console.log(`stdout: ${stdout}`);\n\
\ console.error(`stderr: ${stderr}`);\n });\n}\n```\n\nFor more information\
\ on OS command injection, see OWASP's guide:\nhttps://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html\n\
\nDetected non-literal calls to child_process.exec(). This could lead to a command\n\
injection vulnerability.\n"
metadata:
cwe: CWE-78
owasp:
- A1:2017-Injection
- A03:2021-Injection
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions
source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js
category: security
technology:
- javascript
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
vulnerability_class:
- Command Injection
security-severity: HIGH
languages:
- javascript
- typescript
severity: ERROR
options:
taint_unify_mvars: true
mode: taint
pattern-sources:
- patterns:
- pattern-inside: "function ... (...,$ARG,...) {\n ...\n}\n"
- focus-metavariable: $ARG
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: '$CP = require(''child_process'')
...
'
- pattern-inside: 'import * as $CP from ''child_process''
...
'
- pattern-inside: 'import $CP from ''child_process''
...
'
- pattern-either:
- pattern: $CP.exec($CMD,...)
- pattern: $CP.execSync($CMD,...)
- pattern: $CP.spawn($CMD,...)
- pattern: $CP.spawnSync($CMD,...)
- focus-metavariable: $CMD
pattern-sanitizers:
- pattern: '$CMD = "..."
'
- pattern: '$CMD = ["...",...]
'
- id: rules_lgpl_javascript_exec_rule-shelljs-os-command-exec
patterns:
- pattern-inside: 'require(''shelljs'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$EXEC.exec(<... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: '$EXEC.exec( <... $REQ.$QUERY ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
$EXEC.exec(<... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
$EXEC.exec(<... $INP ...>, ...)
'
message: 'User controlled data in ''shelljs.exec()'' can result in Remote OS Command
Execution.
'
languages:
- javascript
severity: ERROR
metadata:
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-78
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-eval-nodejs
patterns:
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: 'new Function(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: 'new Function(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: 'eval(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: 'eval(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: 'setTimeout(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: 'setTimeout(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: 'setInterval(..., <... $REQ.$QUERY.$VAR ...>, ...)
'
- pattern: 'setInterval(..., <... $REQ.$QUERY ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
new Function(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
new Function(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
eval(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
eval(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
setTimeout(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
setTimeout(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY.$VAR ...>;
...
setInterval(..., <... $INP ...>, ...)
'
- pattern: '$INP = <... $REQ.$QUERY ...>;
...
setInterval(..., <... $INP ...>, ...)
'
message: 'User controlled data in eval() or similar functions may result in Server
Side Injection or Remote Code Injection
'
languages:
- javascript
severity: ERROR
metadata:
cwe: CWE-95
shortDescription: Improper neutralization of directives in dynamically evaluated
code ('Eval Injection')
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: HIGH
- id: rules_lgpl_javascript_eval_rule-vm-runinnewcontext-injection
patterns:
- pattern-inside: 'require(''vm'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$VM.runInNewContext($CODE,<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>;
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$VM.runInNewContext($CODE,<... $REQ.$BODY ...>,...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$BODY} ...>;
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$VM.runInNewContext($CODE,<... $CONTEXT ...>,...)
'
message: 'Untrusted user input in `vm.runInNewContext()` can result in code injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-vm-code-injection
patterns:
- pattern-inside: '$VM = require(''vm'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $VM.runInContext(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $VM.runInContext(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.runInContext($INPUT,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$VM.runInContext($INPUT,...)
'
- pattern: $VM.runInNewContext(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $VM.runInNewContext(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.runInNewContext($INPUT,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$VM.runInNewContext($INPUT,...)
'
- pattern: $VM.runInThisContext(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $VM.runInThisContext(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.runInThisContext($INPUT,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$VM.runInThisContext($INPUT,...)
'
- pattern: $VM.compileFunction(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: $VM.compileFunction(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.compileFunction($INPUT,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
$VM.compileFunction($INPUT,...)
'
- pattern: new $VM.Script(<... $REQ.$QUERY.$FOO ...>,...)
- pattern: new $VM.Script(<... $REQ.$BODY ...>,...)
- pattern: '$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
new $VM.Script($INPUT,...)
'
- pattern: '$INPUT = <... $REQ.$BODY ...>;
...
new $VM.Script($INPUT,...)
'
message: 'Untrusted user input reaching `vm` can result in code injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-yaml-deserialize
patterns:
- pattern-either:
- pattern: 'require(''js-yaml'').load(...)
'
- pattern-inside: '$MOD = require(''js-yaml'')
...
'
- pattern-inside: 'import $MOD from ''js-yaml''
...
'
- pattern: '$MOD.load(...)
'
message: 'User controlled data in ''yaml.load()'' function can result in Remote
Code Injection.
'
languages:
- javascript
- typescript
severity: ERROR
metadata:
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
cwe: CWE-502
shortDescription: Deserialization of Untrusted Data
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_eval_rule-vm2-context-injection
patterns:
- pattern-inside: 'require(''vm2'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: 'new VM({sandbox: <... $REQ.$QUERY.$FOO ...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>;
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>};
...
new VM($OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: 'new NodeVM({sandbox: <... $REQ.$QUERY.$FOO ...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>;
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)
'
- pattern: 'new VM({sandbox: <... $REQ.$BODY ...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$BODY} ...>;
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
new VM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$OPTS = {sandbox: <... $REQ.$BODY ...>};
...
new VM($OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new VM($OPTS,...)
'
- pattern: 'new NodeVM({sandbox: <... $REQ.$BODY ...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$BODY} ...>;
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
new NodeVM({sandbox: <... $CONTEXT ...>},...)
'
- pattern: '$OPTS = {sandbox: <... $REQ.$BODY ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {sandbox: <... $CONTEXT ...>};
...
new NodeVM($OPTS,...)'
message: 'Untrusted user input reaching `vm2` sandbox can result in context injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-vm-runincontext-injection
patterns:
- pattern-inside: 'require(''vm'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>;
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$BODY} ...>;
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$VM.runInContext($CODE,<... $CONTEXT ...>,...)
'
message: 'Untrusted user input in `vm.runInContext()` can result in code injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-serializetojs-deserialize
patterns:
- pattern-either:
- pattern: 'require(''serialize-to-js'').deserialize(...)
'
- pattern-inside: '$MOD = require(''serialize-to-js'')
...
'
- pattern-inside: 'import $MOD from ''serialize-to-js''
...
'
- pattern: '$MOD.deserialize(...)
'
message: 'User controlled data in ''unserialize()'' or ''deserialize()'' function
can result in Object Injection or Remote Code Injection.
'
languages:
- javascript
- typescript
severity: ERROR
metadata:
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
cwe: CWE-502
shortDescription: Deserialization of Untrusted Data
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_eval_rule-sandbox-code-injection
patterns:
- pattern-inside: 'require(''sandbox'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$S.run(<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: '$CODE = <... $REQ.$QUERY.$FOO ...>;
...
$S.run(<... $CODE ...>,...)
'
- pattern: 'new $SANDBOX(...).run(<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: '$CODE = <... $REQ.$QUERY.$FOO ...>;
...
new $SANDBOX(...).run(<... $CODE ...>,...)
'
- pattern: '$S.run(<... $REQ.$BODY ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
$S.run(<... $CODE ...>,...)
'
- pattern: 'new $SANDBOX(...).run(<... $REQ.$BODY ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
new $SANDBOX(...).run(<... $CODE ...>,...)'
message: 'Unrusted data in `sandbox` can result in code injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-node-deserialize
patterns:
- pattern-either:
- pattern: 'require(''node-serialize'').unserialize(...)
'
- pattern-inside: '$MOD = require(''node-serialize'')
...
'
- pattern-inside: 'import $MOD from ''node-serialize''
...
'
- pattern: '$MOD.unserialize(...)
'
message: 'User controlled data in ''unserialize()'' or ''deserialize()'' function
can result in Object Injection or Remote Code Injection.
'
languages:
- javascript
- typescript
severity: ERROR
metadata:
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
cwe: CWE-502
shortDescription: Deserialization of Untrusted Data
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_eval_rule-eval-require
mode: taint
pattern-sources:
- patterns:
- pattern-inside: 'function ($REQ, $RES, ...) {...}
'
- focus-metavariable: $REQ
pattern-sinks:
- patterns:
- pattern: 'require($REQ, ...)
'
- focus-metavariable: $REQ
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n...\nrequire($REQ, ...) \n...\n} \n"
- pattern: '$A = $VALIDATION
...
if($A){
...
require($REQ, ...)
...
}
'
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.includes(...) \n"
- pattern: '$AL.indexOf(...) !== -1
'
- pattern: '$AL.find(...) !== undefined
'
- pattern: '$ALS.has(...)
'
message: "Passing untrusted user input directly into the require() function without\
\ proper \nvalidation or sanitization can possibly cause a vulnerability known\
\ as remote code execution (RCE). \nAn attacker could manipulate the input to\
\ load and execute arbitrary code from external sources, \npotentially leading\
\ to severe security breaches such as data theft, system compromise, \nor unauthorized\
\ access.\nTo mitigate this risk, it's crucial to validate and sanitize user input\n\
thoroughly before passing it to functions like require(), ensuring that only trusted\
\ and safe inputs are utilized.\n\nFollowing is an example of secure validation\
\ against allowlist to prevent the vulnerability:\n```\n// Define a list of explicitly\
\ allowed packages for require\nconst allowedPkgs = [\n 'package1',\n 'package2',\n\
\ 'package3'\n];\n\napp.get(\"/eval/require/7\", async (req, res) => {\n \
\ var isAllowed = allowedPkgs.includes(req.query.name); \n if (isAllowed)\
\ {\n // ok: rules_lgpl_javascript_eval_rule-eval-require\n var\
\ cp = require(req.query.name);\n cp.exec('ls', (error, stdout, stderr)\
\ => {\n console.log(\"exec output : \\n\", stdout)\n }); \
\ \n }\n res.send(\"Please check console logs.\");\n});\n```\n"
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-706
shortDescription: Use of incorrectly-resolved name or reference
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-vm-compilefunction-injection
patterns:
- pattern-inside: 'require(''vm'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$QUERY.$FOO
...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>; ... $CONTEXT = {$NAME: <... $VAR
...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...)
'
- pattern: '$OPTS = {parsingContext: <... $REQ.$QUERY.$FOO ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$BODY
...>},...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = <... {$NAME:$REQ.$BODY} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>; ... $CONTEXT = {$NAME: <... $VAR ...>};
... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...)
'
- pattern: '$OPTS = {parsingContext: <... $REQ.$BODY ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$CONTEXT = <... $REQ.$BODY ...>;
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
- pattern: '$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...)
'
message: 'Untrusted user input in `vm.compileFunction()` can result in code injection.
'
severity: ERROR
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-vm2-code-injection
patterns:
- pattern-inside: 'require(''vm2'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$VM.run(<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: '$CODE = <... $REQ.$QUERY.$FOO ...>;
...
$VM.run(<... $CODE ...>,...)
'
- pattern: 'new VM(...).run(<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: 'new NodeVM(...).run(<... $REQ.$QUERY.$FOO ...>,...)
'
- pattern: '$CODE = <... $REQ.$QUERY.$FOO ...>;
...
new NodeVM(...).run(<... $CODE ...>,...)
'
- pattern: '$CODE = <... $REQ.$QUERY.$FOO ...>;
...
new VMScript(<... $CODE ...>,...)
'
- pattern: '$VM.run(<... $REQ.$BODY ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
$VM.run(<... $CODE ...>,...)
'
- pattern: 'new VM(...).run(<... $REQ.$BODY ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
new VM(...).run($CODE,...)
'
- pattern: 'new NodeVM(...).run(<... $REQ.$BODY ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
new NodeVM(...).run(<... $CODE ...>,...)
'
- pattern: '$CODE = <... $REQ.$BODY ...>;
...
new VMScript(<... $CODE ...>,...)
'
message: 'Untrusted user input reaching `vm2` can result in code injection.
'
severity: WARNING
languages:
- javascript
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-server-side-template-injection
patterns:
- pattern-either:
- pattern-inside: 'require(''handlebars'')
...
'
- pattern-inside: 'require(''pug'')
...
'
- pattern-inside: 'require(''hamljs'')
...
'
- pattern-inside: 'require(''ejs'')
...
'
- pattern-inside: 'require(''squirrelly'')
...
'
- pattern-inside: 'require(''eta'')
...
'
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: '$HB.compile(..., <... $REQ.$FOO ...>, ...)
'
- pattern: '$HB.compile(..., <... $REQ.$FOO.$BAR ...>, ...)
'
- pattern: '$X = <... $REQ.$FOO ...>;
...
$HB.compile(..., <... $X ...>, ...)
'
- pattern: '$X = <... $REQ.$FOO.$BAR ...>;
...
$HB.compile(..., <... $X ...>, ...)
'
- pattern: '$X = $SOURCE.replace(''...'', <... $REQ.$FOO ...>, ...)
...
$HB.compile(..., <... $X ...>, ...)
'
- pattern: '$X = $SOURCE.replace(''...'', <... $REQ.$FOO.$BAR ...>, ...)
...
$HB.compile(..., <... $X ...>, ...)
'
- pattern: '$HB.Compile(..., <... $REQ.$FOO ...>, ...)
'
- pattern: '$HB.Compile(..., <... $REQ.$FOO.$BAR ...>, ...)
'
- pattern: '$X = <... $REQ.$FOO ...>;
...
$HB.Compile(..., <... $X ...>, ...)
'
- pattern: '$X = <... $REQ.$FOO.$BAR ...>;
...
$HB.Compile(..., <... $X ...>, ...)
'
- pattern: '$X = $SOURCE.replace(''...'', <... $REQ.$FOO ...>, ...)
...
$HB.Compile(..., <... $X ...>, ...)
'
- pattern: '$X = $SOURCE.replace(''...'', <... $REQ.$FOO.$BAR ...>, ...)
...
$HB.Compile(..., <... $X ...>, ...)
'
message: 'Untrusted user input in templating engine''s compile() function can result
in Remote Code Execution via server side template injection.
'
languages:
- javascript
severity: ERROR
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code (Code Injection)
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_javascript_eval_rule-grpc-insecure-connection
patterns:
- pattern-either:
- pattern-inside: 'require(''grpc'')
...
'
- pattern-inside: 'import $MOD from ''grpc''
...
'
- pattern: $CREDENTIALS.createInsecure()
message: 'Found an insecure gRPC connection. This creates a connection without encryption
to a gRPC client/server. A malicious attacker could tamper with the gRPC message,
which could compromise the machine.
'
metadata:
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
cwe: CWE-502
shortDescription: Deserialization of Untrusted Data
security-severity: CRITICAL
category: security
severity: ERROR
languages:
- javascript
- typescript
- id: rules_lgpl_javascript_electronjs_rule-electron-context-isolation
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {contextIsolation: false}})
'
- pattern: 'var $X = {webPreferences: {contextIsolation: false}};
'
message: 'Disabling context isolation can introduce Prototype Pollution vulnerabilities.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-1321
shortDescription: Improperly controlled modification of object prototype attributes
('Prototype Pollution')
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_electronjs_rule-electron-allow-http
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {allowRunningInsecureContent: true}})
'
- pattern: 'var $X = {webPreferences: {allowRunningInsecureContent: true}};
'
message: 'Application can load content over HTTP and that makes the app vulnerable
to Man in the middle attacks.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-319
shortDescription: Cleartext Transmission of Sensitive Information
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_electronjs_rule-electron-blink-integration
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {enableBlinkFeatures: ''...''}})
'
- pattern: 'var $X = {webPreferences: {enableBlinkFeatures: ''...''}};
'
message: 'Blink''s expirimental features are enabled in this application. Some of
the features may affect the security of the application.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-272
shortDescription: Least privilege violation
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_electronjs_rule-electron-experimental-features
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {experimentalFeatures: true}})
'
- pattern: 'var $X = {webPreferences: {experimentalFeatures: true}};
'
message: 'Experimental features are not expected to be in production ready applications.
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-272
shortDescription: Least privilege violation
security-severity: CRITICAL
category: security
- id: rules_lgpl_javascript_electronjs_rule-electron-nodejs-integration
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {nodeIntegration: true}})
'
- pattern: 'var $X = {webPreferences: {nodeIntegration: true}};
'
message: 'Node integration exposes node.js APIs to the electron app and this can
introduce remote code execution vulnerabilities to the application if the app
is vulnerable to Cross Site Scripting (XSS).
'
languages:
- javascript
severity: WARNING
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-272
shortDescription: Least privilege violation
security-severity: MEDIUM
category: security
- id: rules_lgpl_javascript_electronjs_rule-electron-disable-websecurity
patterns:
- pattern-either:
- pattern: 'new BrowserWindow({webPreferences: {webSecurity: false}})
'
- pattern: 'var $X = {webPreferences: {webSecurity: false}};
'
message: 'Disabling webSecurity will disable the same-origin policy and allows the
execution of insecure code from any domain.
'
languages:
- javascript
severity: ERROR
metadata:
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-346
shortDescription: Origin validation error
security-severity: CRITICAL
category: security
- id: yaml_spring_rule-SpringActuatorFullyEnabled
languages:
- yaml
severity: WARNING
message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\n\
such as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the\
\ application lacks proper security measures (e.g., authentication and \nauthorization),\
\ sensitive data could be accessed, compromising the application and \nits infrastructure.\
\ This configuration poses a serious risk in production \nenvironments or public-facing\
\ deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose\
\ only the Actuator endpoints required for your use case\n - For production environments,\
\ restrict exposure to non-sensitive endpoints \n like `health` or `info`\n \
\ - Ensure Actuator endpoints are protected with authentication and authorization\
\ \n (e.g., via Spring Security)\n - Use environment-specific configurations\
\ to limit exposure in production\n\nSecure Code Example:\nInstead of include:\
\ \"*\", list only the endpoints you need to expose:\n```\nmanagement:\n endpoints:\n\
\ web:\n exposure:\n include: \"health,info,metrics\"\n```\n\n\
References:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n\
- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n\
- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n"
metadata:
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
shortDescription: Exposure of sensitive system information to an unauthorized
control sphere
category: security
cwe: CWE-497
owasp:
- A01:2021-Broken Access Control
- A3:2017-Sensitive Data Exposure
security-severity: Medium
technology:
- java
patterns:
- pattern: "management:\n ...\n endpoints:\n ...\n web:\n ...\n \
\ exposure:\n ...\n include: \"*\"\n ...\n"
- id: rules_lgpl_swift_other_rule-ios-biometric-acl
patterns:
- pattern-either:
- pattern: .biometryAny
- pattern: .userPresence
- pattern: .touchIDAny
- pattern: SecAccessControlCreateWithFlags(...)
message: "Weak biometric ACL flag is associated with a key stored in Keychain. \n\
With '.biometryAny/.userPresence/.touchIDAny' flag, an attacker with \nthe ability\
\ to add a biometry to the device can authenticate as the \nuser. It is recommended\
\ to use more specific and secure authentication \nmechanisms like '.biometryCurrentSet'\
\ and '.touchIDCurrentSet'.\n\nHere's an example of how to fix the problem by\
\ using .biometryCurrentSet \nfor biometric authentication in Swift:\n```\nimport\
\ LocalAuthentication\n\n// Create an instance of LAContext for biometric authentication\n\
let context = LAContext()\n\n// Check if biometric authentication is available\n\
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error:\
\ nil) {\n // Use biometryCurrentSet for biometric authentication\n context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,\
\ \n localizedReason: \"Authenticate with biometrics\", \n reply:\
\ { success, error in\n if success {\n print(\"Biometric\
\ authentication successful.\")\n // Proceed with authenticated actions\n\
\ } else {\n print(\"Biometric authentication failed:\
\ \n \\(error?.localizedDescription ?? \"Unknown error\")\"\
)\n // Handle authentication failure\n }\n })\n} else\
\ {\n print(\"Biometric authentication not available.\")\n // Fallback to alternative\
\ authentication method\n}\n\n```\n"
languages:
- swift
severity: ERROR
metadata:
category: security
cwe: CWE-305
shortDescription: Authentication bypass by primary weakness
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
security-severity: CRITICAL
- id: rules_lgpl_swift_other_rule-ios-dtls1-used
patterns:
- pattern: $Y.TLSMinimumSupportedProtocolVersion
- pattern-inside: '...
$X = "tls_protocol_version_t.DTLSv10"
...
'
message: "DTLS 1.2 should be used. Detected old version - DTLS 1.0.\nDTLS (Datagram\
\ Transport Layer Security) 1.0 suffers from \nvarious security vulnerabilities\
\ and weaknesses, as it is \nan outdated and less secure protocol compared to\
\ newer \nversions such as DTLS 1.2 or 1.3.\n\nHere's an example of how to use\
\ DTLS 1.2:\n```\nimport Network\n\n// Create a NWConnection instance with DTLS\
\ 1.2\nlet connection = NWConnection(host: NWEndpoint.Host(\"example.com\"), port:\
\ NWEndpoint.Port(\"443\"), using: .dtls)\n\n// Start the connection\nconnection.start(queue:\
\ .main)\n\n// Handle connection state changes\nconnection.stateUpdateHandler\
\ = { newState in\n switch newState {\n case .ready:\n print(\"Connection\
\ ready.\")\n // Perform data transfer or other operations\n case .failed(let\
\ error):\n print(\"Connection failed with error: \\(error)\")\n default:\n\
\ break\n }\n}\n```\n"
languages:
- swift
severity: WARNING
metadata:
category: security
cwe: CWE-757
shortDescription: Selection of less-secure algorithm during negotiation ('algorithm
downgrade')
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
- id: rules_lgpl_swift_other_rule-ios-keychain-weak-accessibility-value
pattern-either:
- pattern: kSecAttrAccessibleAlways
- pattern: kSecAttrAccessibleAfterFirstUnlock
message: "A key stored in the Keychain is using a weak accessibility value. \n\n\
kSecAttrAccessibleAlways allows access to the keychain item at all \ntimes, even\
\ when the device is locked. Storing sensitive data with \nthis accessibility\
\ option means that the data is accessible to anyone \nwho gains physical access\
\ to the device, regardless of whether it's \nlocked or not. This increases the\
\ risk of unauthorized access to \nsensitive information. kSecAttrAccessibleAfterFirstUnlock\
\ allows access\nto the keychain item only after the device has been unlocked\
\ once after\na reboot. While this provides some level of protection, the data\
\ becomes\naccessible as soon as the device is unlocked for the first time after\
\ a\nreboot. If sensitive data is stored with this accessibility option, it \n\
could still be accessed by an attacker who gains physical access to the\ndevice\
\ before it's unlocked for the first time after a reboot.\n\nTo mitigate these\
\ security risks, it's important to use the appropriate \naccessibility option\
\ based on the sensitivity of the data being stored. \nFor sensitive data that\
\ should only be accessible when the device is \nunlocked, the kSecAttrAccessibleWhenUnlocked\
\ or \nkSecAttrAccessibleWhenUnlockedThisDeviceOnly \noptions should be used.\n\
\nHere's an example code that fixes the problem by using the \nkSecAttrAccessibleWhenUnlocked\
\ option:\n```\nimport Foundation\nimport Security\n\n// Define the data to be\
\ stored in the keychain\nlet secretData = \"superSecretData\".data(using: .utf8)!\n\
\n// Create query dictionary to specify the keychain item\nlet query: [String:\
\ Any] = [\n kSecClass as String: kSecClassGenericPassword,\n \
\ kSecAttrService as String: \"com.example.myApp\",\n kSecAttrAccount\
\ as String: \"userPassword\",\n kSecValueData as String: secretData,\n\
\ kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked\n]\n\n\
// Add the keychain item\nlet status = SecItemAdd(query as CFDictionary, nil)\n\
if status == errSecSuccess {\n print(\"Secret data successfully stored in keychain.\"\
)\n} else {\n print(\"Error storing secret data in keychain: \\(status)\")\n\
}\n```\n"
languages:
- swift
severity: WARNING
metadata:
category: security
cwe: CWE-305
shortDescription: Authentication bypass by primary weakness
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
security-severity: MEDIUM
- id: rules_lgpl_swift_other_rule-ios-file-no-special
pattern-either:
- pattern: .noFileProtection
- pattern: FileProtectionType.none
message: "The file has no special protections associated with it.\nUsing .noFileProtection\
\ or FileProtectionType.none for \nfile protection means that the file is not\
\ encrypted on disk, \nleaving it vulnerable to unauthorized access if the device\
\ is \ncompromised or if the file is accessed outside of the app's \nsandbox.\
\ To enhance security, it's crucial to use appropriate \nfile protection attributes\
\ based on the sensitivity of the data \nbeing stored. For sensitive data, you\
\ should use file protection \noptions that encrypt the data on disk, such as\
\ \nFileProtectionType.complete or \nFileProtectionType.completeUnlessOpen.\n\n\
Here's an example of how to fix the problem:\n```\nimport Foundation \n// Define\
\ the file URL\nlet fileURL = URL(fileURLWithPath: \"path/to/file\")\n// Define\
\ data to be written to the file\nlet data = \"Sensitive data\".data(using: .utf8)!\n\
// Write data to the file with complete file protection\ndo {\n try data.write(to:\
\ fileURL, options: .completeFileProtection)\n print(\"Data written to file with\
\ complete file protection.\")\n} catch {\n print(\"Error writing data to file:\
\ \\(error)\")\n}\n```\n"
languages:
- swift
severity: ERROR
metadata:
category: security
cwe: CWE-312
shortDescription: Cleartext storage of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: CRITICAL
- id: rules_lgpl_swift_other_rule-ios-tls3-not-used
pattern-either:
- patterns:
- pattern: $X.TLSMinimumSupportedProtocolVersion = $VAL
- metavariable-pattern:
metavariable: $VAL
pattern-either:
- pattern: '.TLSv1_0
'
- pattern: '.TLSv1_1
'
- pattern: '.TLSv1_2
'
message: "The app uses TLS 1.0, TLS 1.1 or TLS 1.2. TLS 1.3 should be used instead.\n\
TLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to \na number\
\ of attacks against the vulnerable versions. Use of a deprecated \nTLS version\
\ may result in the unauthorized retrieval of sensitive \ninformation. It is strongly\
\ recommended that all TLS connections\nuse TLS 1.3\n\nTLS 1.3 includes several\
\ security improvements over previous versions, such\nas stronger cryptographic\
\ algorithms and negotiation mechanisms, reducing \nthe risk of security vulnerabilities\
\ and attacks like BEAST and POODLE.\n\n\nExample using TLS 1.3:\n```\nimport\
\ Foundation\n// Create a URLSession configuration with TLS 1.3 support\nlet configuration\
\ = URLSessionConfiguration.default\nconfiguration.tlsMinimumSupportedProtocol\
\ = .TLSv13\n// Create a URLSession with the custom configuration\nlet session\
\ = URLSession(configuration: configuration) \n// Define the URL to connect\
\ to\nlet url = URL(string: \"https://example.com\")!\n// Create a data task to\
\ fetch data from the URL\nlet task = session.dataTask(with: url) { data, response,\
\ error in\n // Handle response\n if let error = error {\n print(\"Error:\
\ \\(error)\")\n return\n }\n if let httpResponse = response as? HTTPURLResponse\
\ {\n print(\"Status code: \\(httpResponse.statusCode)\")\n } \n if let\
\ data = data {\n // Process received data\n print(\"Received data: \\(data)\"\
)\n }\n}\n// Start the data task\ntask.resume()\n```\n"
languages:
- swift
severity: ERROR
metadata:
category: security
cwe: CWE-757
shortDescription: Selection of less-secure algorithm during negotiation ('algorithm
downgrade')
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: CRITICAL
- id: properties_spring_rule-SpringActuatorFullyEnabled
languages:
- generic
severity: WARNING
message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\n\
such as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the\
\ application lacks proper security measures (e.g., authentication and \nauthorization),\
\ sensitive data could be accessed, compromising the application and \nits infrastructure.\
\ This configuration poses a serious risk in production \nenvironments or public-facing\
\ deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose\
\ only the Actuator endpoints required for your use case\n - For production environments,\
\ restrict exposure to non-sensitive endpoints \n like `health` or `info`\n \
\ - Ensure Actuator endpoints are protected with authentication and authorization\
\ \n (e.g., via Spring Security)\n - Use environment-specific configurations\
\ to limit exposure in production\n\nSecure Code Example:\nInstead of include:\
\ \"*\", list only the endpoints you need to expose:\n```\nmanagement.endpoints.web.exposure.include=\"\
health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n\
- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n\
- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n"
metadata:
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
shortDescription: Exposure of sensitive system information to an unauthorized
control sphere
category: security
cwe: CWE-497
owasp:
- A01:2021-Broken Access Control
- A3:2017-Sensitive Data Exposure
security-severity: Medium
technology:
- java
paths:
include:
- '*properties'
pattern: management.endpoints.web.exposure.include=*
- id: php_phpinfo_rule-phpinfo-use
pattern: phpinfo(...);
message: The 'phpinfo' function may reveal sensitive information about your environment.
metadata:
cwe: CWE-497
shortDescription: Exposure of sensitive system information to an unauthorized
control sphere
references:
- https://www.php.net/manual/en/function.phpinfo
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php
category: security
technology:
- php
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
cwe2021-top25: true
subcategory:
- vuln
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
security-severity: MEDIUM
languages:
- php
severity: WARNING
- id: php_ftp_rule-ftp-use
patterns:
- pattern: $FUNC(...);
- metavariable-regex:
metavariable: $FUNC
regex: ftp_.+
message: FTP allows for unencrypted file transfers. Consider using an encrypted
alternative.
metadata:
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
references:
- https://www.php.net/manual/en/intro.ftp.php
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php
category: security
technology:
- php
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
security-severity: MEDIUM
languages:
- php
severity: WARNING
- id: php_crypto_rule-weak-crypto
patterns:
- pattern: $FUNC(...);
- metavariable-regex:
metavariable: $FUNC
regex: crypt|md5|md5_file|sha1|sha1_file|str_rot13
message: Detected usage of weak crypto function. Consider using stronger alternatives.
metadata:
cwe: CWE-328
shortDescription: Use of weak hash
references:
- https://www.php.net/manual/en/book.sodium.php
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php
category: security
technology:
- php
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Insecure Hashing Algorithm
security-severity: MEDIUM
languages:
- php
severity: WARNING
- id: php_file_rule-file-inclusion
message: Detected non-constant file inclusion. This can lead to local file inclusion
(LFI) or remote file inclusion (RFI) if user input reaches this statement. LFI
and RFI could lead to sensitive files being obtained by attackers. Instead, explicitly
specify what to include. If that is not a viable solution, validate user input
thoroughly.
metadata:
cwe: CWE-98
shortDescription: Improper control of filename for include/require statement in
PHP program ('PHP Remote File Inclusion')
references:
- https://www.php.net/manual/en/function.include.php
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/EasyRFISniff.php
- https://en.wikipedia.org/wiki/File_inclusion_vulnerability#Types_of_Inclusion
category: security
technology:
- php
owasp:
- A1:2017-Injection
- A03:2021-Injection
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
security-severity: CRITICAL
languages:
- php
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: $_GET
- pattern: $_POST
- pattern: $_COOKIE
- pattern: $_REQUEST
- pattern: $_SERVER
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern-inside: basename($PATH, ...)
- pattern-inside: linkinfo($PATH, ...)
- pattern-inside: readlink($PATH, ...)
- pattern-inside: realpath($PATH, ...)
- pattern-inside: include_safe(...)
pattern-sinks:
- patterns:
- pattern-inside: $FUNC(...);
- pattern: $VAR
- metavariable-regex:
metavariable: $FUNC
regex: \b(include|include_once|require|require_once)\b
- id: php_backticks_rule-backticks-use
pattern: '`...`;'
message: Backticks use may lead to command injection vulnerabilities.
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code ('Code Injection')
references:
- https://www.php.net/manual/en/language.operators.execution.php
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php
category: security
technology:
- php
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe2022-top25: true
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
security-severity: CRITICAL
languages:
- php
severity: ERROR
- id: php_assert_rule-assert-use
mode: taint
pattern-sources:
- pattern-either:
- patterns:
- pattern-either:
- pattern: $_GET
- pattern: $_POST
- pattern: $_COOKIE
- pattern: $_REQUEST
- pattern: $_SERVER
- patterns:
- pattern: 'Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... })
'
- focus-metavariable: $ARG
pattern-sinks:
- patterns:
- pattern: assert($SINK, ...);
- pattern-not: assert("...", ...);
- pattern: $SINK
message: Calling assert with user input is equivalent to eval'ing.
metadata:
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-95
shortDescription: Improper neutralization of directives in dynamically evaluated
code ('Eval Injection')
references:
- https://www.php.net/manual/en/function.assert
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php
category: security
technology:
- php
subcategory:
- vuln
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
security-severity: CRITICAL
languages:
- php
severity: ERROR
- id: php_mcrypt_rule-mcrypt-use
patterns:
- pattern: $FUNC(...);
- metavariable-regex:
metavariable: $FUNC
regex: (mcrypt_|mdecrypt_).+
message: Mcrypt functionality has been deprecated and/or removed in recent PHP versions.
Consider using Sodium or OpenSSL.
metadata:
cwe: CWE-676
shortDescription: Use of potentially dangerous function
references:
- https://www.php.net/manual/en/intro.mcrypt.php
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php
category: security
owasp:
- A9:2017-Using Components with Known Vulnerabilities
- A06:2021-Vulnerable and Outdated Components
technology:
- php
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Dangerous Method or Function
security-severity: MEDIUM
languages:
- php
severity: WARNING
- id: php_exec_rule-exec-use
patterns:
- pattern: $FUNC(...);
- pattern-not: $FUNC('...', ...);
- metavariable-regex:
metavariable: $FUNC
regex: exec|passthru|proc_open|popen|shell_exec|system|pcntl_exec
message: Executing non-constant commands. This can lead to command injection.
metadata:
cwe: CWE-94
shortDescription: Improper control of generation of code ('Code Injection')
references:
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php
category: security
technology:
- php
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe2022-top25: true
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
security-severity: CRITICAL
languages:
- php
severity: ERROR
- id: php_eval_rule-eval-use
patterns:
- pattern: eval(...);
- pattern-not: eval('...');
message: Evaluating non-constant commands. This can lead to command injection.
metadata:
cwe: CWE-78
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
references:
- https://www.php.net/manual/en/function.eval
- https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/NoEvalsSniff.php
category: security
technology:
- php
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Command Injection
security-severity: CRITICAL
languages:
- php
severity: ERROR
- id: kotlin_ssrf_rule-SSRF
languages:
- kotlin
message: 'Server-Side Request Forgery occur when a web server executes a request
to a user supplied
destination parameter that is not validated. Such vulnerabilities could allow
an attacker to
access internal services or to launch attacks from your web server.
'
metadata:
shortDescription: Server-Side Request Forgery (SSRF)
category: security
cwe: CWE-918
owasp:
- A1:2017-Injection
- A10:2021-Server-Side Request Forgery
security-severity: CRITICAL
severity: ERROR
pattern-either:
- patterns:
- pattern-either:
- pattern-inside: 'import java.net.*;
...
'
- pattern-inside: 'import java.net.URL;
...
'
- pattern-inside: 'import java.net.URI;
...
'
- pattern: $TYPE(...). ... .$FUNC
- pattern-not: $TYPE("..."). ... .$FUNC
- metavariable-pattern:
metavariable: $FUNC
pattern-either:
- pattern: connect
- pattern: GetContent
- pattern: openConnection
- pattern: openStream
- pattern: getContent
- pattern: content
- metavariable-pattern:
metavariable: $TYPE
pattern-either:
- pattern: URL
- pattern: java.net.URL
- pattern: URI
- pattern: java.net.URI
- patterns:
- pattern-either:
- pattern-inside: 'import java.net.*;
...
'
- pattern-inside: 'import java.net.InetSocketAddress;
...
'
- pattern: 'InetSocketAddress(..., $PORT)
'
- pattern-not: 'InetSocketAddress("...", $PORT)
'
- id: kotlin_crypto_rule-CipherECBMode
languages:
- kotlin
message: 'An authentication cipher mode which provides better confidentiality of
the encrypted data
should be used instead of Electronic Code Book (ECB) mode, which does not provide
good
confidentiality. Specifically, ECB mode produces the same output for the same
input each time.
This allows an attacker to intercept and replay the data.
'
metadata:
category: security
cwe: CWE-326
shortDescription: Inadequate Encryption Strength
technology:
- kotlin
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...)
- metavariable-regex:
metavariable: $TRANSFORMATION
regex: ^"[^/]*/ECB(/.*)?"$
- id: kotlin_crypto_rule-InsufficientKeySizeRsa
languages:
- kotlin
message: 'Detected an insufficient key size for DSA. NIST recommends a key size
of 2048 or higher.
'
metadata:
shortDescription: Inadequate encryption strength
category: security
cwe: CWE-326
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- patterns:
- pattern-inside: '$GEN = KeyPairGenerator.getInstance($ALG, ...);
...
'
- pattern-either:
- pattern: $VAR.initialize($SIZE, ...);
- pattern: java.security.spec.RSAKeyGenParameterSpec($SIZE,...);
- metavariable-comparison:
comparison: $SIZE < 2048
metavariable: $SIZE
- metavariable-regex:
metavariable: $ALG
regex: '"(RSA|DSA)"'
- id: kotlin_crypto_rule-CipherIntegrity
languages:
- kotlin
message: 'The ciphertext produced is susceptible to alteration by an adversary.
This mean that the
cipher provides no way to detect that the data has been tampered with. If the
ciphertext can be
controlled by an attacker, it could be altered without detection.
'
severity: ERROR
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- kotlin
security-severity: CRITICAL
patterns:
- pattern: 'javax.crypto.Cipher.getInstance($TRANSFORMATION, ...)
'
- metavariable-pattern:
metavariable: $TRANSFORMATION
patterns:
- pattern-regex: ^"[^/]*(/(CBC|OFB|CTR|ECB)(/.*)?)?"$
- pattern-not-regex: ^"(ECIES|RSA)(/|"$)
- id: kotlin_crypto_rule-WeakTLSProtocolVersion
languages:
- kotlin
message: 'The application was found enabling insecure TLS protocol versions. When
enabling protocol
versions for an `SSLContext`, only the following versions should be allowed:
- TLSv1.2
- TLSv1.3
- DTLSv1.2
- DTLSv1.3
To mitigate potential security risks, it is strongly advised to enforce TLS 1.2
as the minimum
protocol version and disallow older versions such as TLS 1.0. Do note that newer
versions of
Java do not even support TLS 1.0 and will throw `NoSuchAlgorithmException`. Versions
of TLS
prior to 1.2 could expose the connection to downgrade attacks, where an adversary
intercepts
the
connection and alters the requested protocol version to be a less secure one.
In many scenarios, relying on the default system configuration does not meet compliance
standards. This is due to the application being deployed across diverse systems
with varying
configurations and Java versions. While the default value may be secure on modern
and
up-to-date systems, it may not hold true for older systems. Consequently, it is
highly
recommended to explicitly define a secure configuration in all cases.
Example configuring an SSLContext with TLSv1.2:
```
// Create an SSLContext with TLSv1.2 explicitly
SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2,
DTLSv1.3
// Alternatively, set the enabled protocols
SSLContext serverSslContext = SSLContext.getInstance("TLS");
SSLEngine serverEngine = serverSslContext.createSSLEngine();
// Calling setEnabledProtocols will override the original context''s configured
protocol version
serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" });
```
For more information on `SSLContext` see:
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html
For more information on MiTM attacks see:
- https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack
'
metadata:
shortDescription: Inadequate encryption strength
category: security
cwe: CWE-326
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- pattern-inside: 'import javax.net.ssl.*;
...
'
- pattern-inside: 'import javax.net.ssl.SSLContext;
...
'
- pattern-either:
- pattern-inside: 'SSLContext.getInstance("$UNSAFE_VERSION");
'
- pattern-inside: 'SSLContext.getInstance(...);
...
$ENGINE.setEnabledProtocols(arrayOf(...,"$UNSAFE_VERSION",...));
'
- pattern-not:
patterns:
- pattern-inside: '$C = SSLContext.getInstance(...);
...
$ENGINE.setEnabledProtocols(arrayOf(...,"$DT_GOODNESS",...));
'
- metavariable-regex:
metavariable: $DT_GOODNESS
regex: ^D?TLSv1\.[23]$
- pattern-not:
patterns:
- pattern-inside: '$C = SSLContext.getInstance(...);
...
$E = $C.createSSLEngine()
...
$E.enabledProtocols = arrayOf(...,"$DT_GOODNESS",...)
'
- metavariable-regex:
metavariable: $DT_GOODNESS
regex: ^DTLSv1\.[23]$
- metavariable-regex:
metavariable: $UNSAFE_VERSION
regex: ^(TLS|(D)?TLSv1.(0|1))$
- id: kotlin_crypto_rule-NullCipher
languages:
- kotlin
message: 'The NullCipher implements the Cipher interface by returning ciphertext
identical to the
supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate.
Avoid
using the NullCipher. Its accidental use can introduce a significant confidentiality
risk.
'
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- kotlin
security-severity: MEDIUM
pattern: javax.crypto.NullCipher()
- id: kotlin_crypto_rule-CipherDESedeInsecure
languages:
- kotlin
message: 'Triple DES (also known as 3DES or DESede) is considered strong ciphers
for modern
applications. NIST recommends the usage of AES block ciphers instead of 3DES.
'
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern-inside: javax.crypto.Cipher.getInstance($ALG, ...)
- metavariable-regex:
metavariable: $ALG
regex: (?i)^"DESede(/|"$)
- id: kotlin_crypto_rule-CipherDESInsecure
languages:
- kotlin
message: 'DES is considered strong ciphers for modern applications. Currently, NIST
recommends the usage
of AES block ciphers instead of DES.
'
severity: WARNING
metadata:
shortDescription: Inadequate encryption strength
category: security
cwe: CWE-326
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern-inside: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...)
- metavariable-regex:
metavariable: $TRANSFORMATION
regex: ^"DES(/|"$)
- id: kotlin_crypto_rule-RsaNoPadding
languages:
- kotlin
message: 'The software uses the RSA algorithm but does not incorporate Optimal Asymmetric
Encryption Padding (OAEP), which might weaken the encryption.
'
metadata:
shortDescription: Use of RSA algorithm without OAEP
category: security
cwe: CWE-780
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
severity: WARNING
pattern-either:
- patterns:
- pattern: '$VAR = "$ALG";
...
javax.crypto.Cipher.getInstance($VAR);
'
- metavariable-regex:
metavariable: $ALG
regex: .*RSA.*NoPadding.*
- patterns:
- pattern: javax.crypto.Cipher.getInstance($ALG,...);
- metavariable-regex:
metavariable: $ALG
regex: .*RSA.*NoPadding.*
- id: kotlin_crypto_rule-BlowfishKeySize
languages:
- kotlin
message: 'A small key size makes the ciphertext vulnerable to brute force attacks.
At least 128 bits of
entropy should be used when generating the key if use of Blowfish is required.
'
severity: WARNING
metadata:
category: security
shortDescription: Inadequate encryption strength
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
cwe: CWE-326
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern-inside: '$KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...);
...
$KEYGEN.init($KEY_SIZE);
'
- metavariable-comparison:
comparison: $KEY_SIZE < 128
metavariable: $KEY_SIZE
- id: kotlin_crypto_rule-CustomMessageDigest
languages:
- kotlin
message: 'Implementing a custom MessageDigest is error-prone. National Institute
of Standards and
Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224,
or
SHA-512/256.
'
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A6:2017-Security Misconfiguration
- A04:2021-Insecure Design
technology:
- kotlin
security-severity: MEDIUM
pattern: "class $CLAZZ : java.security.MessageDigest(...) {\n ...\n}\n"
- id: kotlin_crypto_rule-CipherPaddingOracle
languages:
- kotlin
message: 'This specific mode of CBC with PKCS5Padding is susceptible to padding
oracle attacks. An
adversary could potentially decrypt the message if the system exposed the difference
between
plaintext with invalid padding or valid padding. The distinction between valid
and invalid
padding is usually revealed through distinct error messages being returned for
each condition.
'
severity: ERROR
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- java
security-severity: CRITICAL
patterns:
- pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION)
- metavariable-regex:
metavariable: $TRANSFORMATION
regex: ^"[^/]*/CBC/PKCS5Padding
- metavariable-pattern:
metavariable: $TRANSFORMATION
patterns:
- pattern-not-regex: ^"(RSA|ECIES)/
- id: kotlin_crypto_rule-WeakMessageDigest
languages:
- kotlin
message: 'DES is considered strong ciphers for modern applications. Currently, NIST
recommends the usage
of AES block ciphers instead of DES.
'
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5)
category: security
cwe: CWE-327
owasp:
- A6:2017-Security Misconfiguration
- A04:2021-Insecure Design
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern-either:
- pattern: MessageDigest.getInstance($ALG, ...)
- pattern: Signature.getInstance($ALG, ...)
- metavariable-regex:
metavariable: $ALG
regex: .*(MD5|MD4|MD2|SHA1|SHA-1).*
- id: kotlin_crypto_rule-HazelcastSymmetricEncryption
languages:
- kotlin
message: 'The network communications for Hazelcast is configured to use a symmetric
cipher (probably DES
or Blowfish). Those ciphers alone do not provide integrity or secure authentication.
The use of
asymmetric encryption is preferred.
'
severity: WARNING
metadata:
shortDescription: Inadequate encryption strength
category: security
cwe: CWE-326
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- kotlin
security-severity: MEDIUM
pattern: com.hazelcast.config.SymmetricEncryptionConfig()
- id: kotlin_crypto_rule-WeakTLSProtocol
languages:
- kotlin
message: 'A HostnameVerifier that accept any host are often use because of certificate
reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks
attacks since the client will trust any certificate.
'
metadata:
shortDescription: Improper certificate validation
category: security
cwe: CWE-295
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- pattern: org.apache.http.impl.client.DefaultHttpClient()
- pattern: javax.net.ssl.SSLContext.getInstance("SSL")
- id: kotlin_strings_rule-ModifyAfterValidation
languages:
- kotlin
message: 'CERT: IDS11-J. Perform any string modifications before validation
'
metadata:
shortDescription: Collapse of data into unsafe value
category: security
cwe: CWE-182
confidence: HIGH
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-inside: '$PATTERN = Pattern.compile(...)
...
'
- pattern-inside: '$PATTERN.matcher($VAR)
...
'
- pattern-either:
- pattern: '$VAR + $OTHER
'
- patterns:
- pattern: '$VAR.$METHOD(...)
'
- metavariable-regex:
metavariable: $METHOD
regex: (replace|replaceAll|replaceFirst|concat)
- id: kotlin_strings_rule-NormalizeAfterValidation
languages:
- kotlin
message: 'IDS01-J. Normalize strings before validating them
'
metadata:
shortDescription: 'Incorrect behavior order: validate before canonicalize'
category: security
cwe: CWE-180
confidence: HIGH
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern: '$Y = java.util.regex.Pattern.compile("[<>]");
...
$Y.matcher($VAR);
...
java.text.Normalizer.normalize($VAR, ...);'
- id: kotlin_strings_rule-BadHexConversion
languages:
- kotlin
message: 'When converting a byte array containing a hash signature to a human readable
string, a
conversion mistake can be made if the array is read byte by byte.
'
metadata:
shortDescription: Incorrect type conversion or cast
cwe: CWE-704
category: security
confidence: HIGH
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-inside: '$B_ARR = ($MD: java.security.MessageDigest).digest(...);
...
'
- pattern-either:
- pattern: "for($B in $B_ARR) {\n ...\n $B_TOSTR\n}\n"
- pattern: "while(...) {\n ...\n $B_TOSTR\n}\n"
- pattern: "do {\n ...\n $B_TOSTR\n} while(...)\n"
- metavariable-pattern:
metavariable: $B_TOSTR
patterns:
- pattern-either:
- pattern: java.lang.Integer.toHexString($B_TOINT)
- pattern: Integer.toHexString($B_TOINT)
- pattern: $B_TOINT.toHexString(...)
- metavariable-pattern:
metavariable: $B_TOINT
pattern-either:
- pattern: $B_ARR[...].toInt()
- pattern: $B_ARR[...]
- pattern: $B.toInt()
- pattern: $B
- id: kotlin_strings_rule-FormatStringManipulation
languages:
- kotlin
message: 'Allowing user input to control format parameters could enable an attacker
to cause exceptions
to be thrown or leak information.Attackers may be able to modify the format string
argument,
such that an exception is thrown. If this exception is left uncaught, it may crash
the
application. Alternatively, if sensitive information is used within the unused
arguments,
attackers may change the format string to reveal this information.
'
metadata:
shortDescription: Use of externally-controlled format string
cwe: CWE-134
category: security
confidence: HIGH
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-either:
- patterns:
- pattern-inside: '$INPUT = ($REQ: HttpServletRequest).getParameter(...)
...
'
- pattern-inside: '$FORMAT_STR = ... + $INPUT
...
'
- patterns:
- pattern-inside: '$INPUT = ($REQ: HttpServletRequest).getParameter(...)
...
'
- pattern-inside: '$FORMAT_STR = ... + $INPUT + ...
...
'
- pattern-inside: '$FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...)
+ ...
...
'
- pattern-inside: '$FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...)
...
'
- pattern-either:
- pattern: String.format($FORMAT_STR, ...)
- pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)
- patterns:
- pattern-inside: '$F = java.util.Formatter(...)
...
'
- pattern-either:
- pattern: $F.format($FORMAT_STR, ...)
- pattern: $F.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)
- pattern: '($F: java.io.PrintStream).printf($FORMAT_STR, ...)'
- pattern: '($F: java.io.PrintStream).printf(java.util.Locale.$LOCALE, $FORMAT_STR,
...)'
- pattern: '($F: java.io.PrintStream).format($FORMAT_STR, ...)'
- pattern: '($F: java.io.PrintStream).format(java.util.Locale.$LOCALE, $FORMAT_STR,
...)'
- pattern: System.out.printf($FORMAT_STR, ...)
- pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...)
- pattern: System.out.format($FORMAT_STR, ...)
- pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)
- id: kotlin_password_rule-ConstantDBPassword
pattern: java.sql.DriverManager.getConnection($URI, $USR, "...")
message: 'A potential hard-coded password was identified in a database connection
string.
Passwords should not be stored directly in code
but loaded from secure locations such as a Key Management System (KMS).
The purpose of using a Key Management System is so access can be audited and keys
easily
rotated
in the event of a breach. By hardcoding passwords, it will be extremely difficult
to determine
when or if, a key is compromised.
The recommendation on which KMS to use depends on the environment the application
is running
in:
- For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs)
- For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/)
- For on premise or other alternatives to cloud providers, consider [Hashicorp''s
Vault](https://www.vaultproject.io/)
- For other cloud providers, please see their documentation
'
severity: ERROR
metadata:
shortDescription: Use of hard-coded password
category: security
cwe: CWE-259
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
technology:
- kotlin
security-severity: Critical
languages:
- kotlin
- id: kotlin_password_rule-EmptyDBPassword
pattern: java.sql.DriverManager.getConnection($URI, $USR, "");
message: 'The application does not provide authentication when communicating a database
server. It is strongly recommended that the database server be configured with
authentication and restrict what queries users can execute.
Please see your database server''s documentation on how to configure a password.
Additionally, passwords should not be stored directly in code
but loaded from secure locations such as a Key Management System (KMS).
The purpose of using a Key Management System is so access can be audited and keys
easily
rotated
in the event of a breach. By hardcoding passwords, it will be extremely difficult
to determine
when or if, a key is compromised.
The recommendation on which KMS to use depends on the environment the application
is running
in:
- For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs)
- For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/)
- For on premise or other alternatives to cloud providers, consider [Hashicorp''s
Vault](https://www.vaultproject.io/)
- For other cloud providers, please see their documentation
'
severity: ERROR
metadata:
shortDescription: Missing authentication for critical function (database)
category: security
cwe: CWE-306
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
technology:
- kotlin
security-severity: Critical
languages:
- kotlin
- id: kotlin_password_rule-HardcodePassword
languages:
- kotlin
message: 'A potential hard-coded password was identified in the source code.
Passwords should not be stored directly in code
but loaded from secure locations such as a Key Management System (KMS).
The purpose of using a Key Management System is so access can be audited and keys
easily
rotated
in the event of a breach. By hardcoding passwords, it will be extremely difficult
to determine
when or if, a key is compromised.
The recommendation on which KMS to use depends on the environment the application
is running
in:
- For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs)
- For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/)
- For on premise or other alternatives to cloud providers, consider [Hashicorp''s
Vault](https://www.vaultproject.io/)
- For other cloud providers, please see their documentation
'
severity: ERROR
metadata:
shortDescription: Use of hard-coded password
category: security
cwe: CWE-259
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
technology:
- kotlin
security-severity: High
pattern-either:
- pattern: java.security.KeyStore.PasswordProtection("...".toCharArray())
- pattern: java.security.KeyStore.getInstance(...).load(..., "...".toCharArray())
- pattern: '($KS: java.security.KeyStore).load(..., "...".toCharArray())'
- pattern: KeyManagerFactory.getInstance(...).init(..., "...".toCharArray())
- pattern: '($KMF: KeyManagerFactory).init(..., "...".toCharArray())'
- pattern: PBEKeySpec("...", ...)
- pattern: PasswordAuthentication("...", "...")
- pattern: '($CB: PasswordCallback).setPassword("...")'
- pattern: KerberosKey(...,"...",...)
- pattern: java.sql.DriverManager.getConnection(..., "...")
- pattern: io.vertx.ext.web.handler.CSRFHandler.create(..., "...")
- pattern: $S.setPassword("...")
- id: kotlin_templateinjection_rule-TemplateInjection
languages:
- kotlin
message: 'A malicious user in control of a template can run malicious code on the
server-side. Velocity templates should be seen as scripts.
'
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
pattern-either:
- patterns:
- pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR)
- pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...")
- patterns:
- pattern-not-inside: '$C = ($CFG: freemarker.template.Configuration).getTemplate("...");
...
'
- pattern-inside: '$C = ($CFG: freemarker.template.Configuration).getTemplate($IN);
...
'
- pattern: $C.process(...)
- patterns:
- pattern-inside: 'import com.mitchellbosecke.pebble.PebbleEngine;
...
'
- pattern-inside: '$C = $T.getTemplate($IN);
...
'
- pattern-not-inside: '$C = $T.getTemplate("...");
...
'
- pattern: $C.evaluate(...)
- id: kotlin_xxe_rule-SaxParserXXE
languages:
- kotlin
message: 'XML External Entity (XXE) attacks can occur when an XML parser supports
XML
entities while processing XML received from an untrusted source.
'
metadata:
shortDescription: Improper restriction of XML external entity reference ('XXE')
category: security
cwe: CWE-611
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-inside: '$SF = SAXParserFactory.newInstance()
...
'
- pattern-not-inside: '$SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
...
'
- pattern-not-inside: '$SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
true);
...
'
- pattern-inside: '$P = $SFP.newSAXParser();
...
'
- pattern: $P.parse(...);
- id: kotlin_xxe_rule-XMLRdr
languages:
- kotlin
message: 'XML External Entity (XXE) attacks can occur when an XML parser supports
XML
entities while processing XML received from an untrusted source.
'
metadata:
shortDescription: Improper restriction of XML external entity reference ('XXE')
category: security
cwe: CWE-611
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-inside: '$R = XMLReaderFactory.createXMLReader()
...
'
- pattern-not-inside: '$R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
...
'
- pattern: $R.parse(...)
- id: kotlin_xxe_rule-XMLStreamRdr
languages:
- kotlin
message: 'XML External Entity (XXE) attacks can occur when an XML parser supports
XML
entities while processing XML received from an untrusted source.
'
metadata:
shortDescription: Improper restriction of XML external entity reference ('XXE')
category: security
cwe: CWE-611
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-inside: '$SF = XMLInputFactory.newFactory();
...
'
- pattern-not-inside: '$SF.setProperty(XMLInputFactory.SUPPORT_DTD, false);
...
'
- pattern-not-inside: '$SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
false);
...
'
- pattern-not-inside: '$SF.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
...
'
- pattern-not-inside: '$SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
Boolean.FALSE);
...
'
- pattern: $SF.createXMLStreamReader(...)
- id: kotlin_file_rule-FilenameUtils
languages:
- kotlin
message: 'A file is opened to read its content. The filename comes from an input
parameter. If an unfiltered parameter is passed to this file API, files from an
arbitrary filesystem location could be read.
'
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
technology:
- kotlin
category: security
severity: WARNING
patterns:
- pattern-inside: 'import org.apache.commons.io.FilenameUtils
...
'
- pattern-either:
- pattern: normalize(...)
- pattern: getExtension(...)
- pattern: isExtensions(...)
- pattern: getName(...)
- pattern: getBaseName(...)
- pattern: org.apache.commons.io.FilenameUtils.normalize(...)
- pattern: org.apache.commons.io.FilenameUtils.getExtension(...)
- pattern: org.apache.commons.io.FilenameUtils.isExtensions(...)
- pattern: org.apache.commons.io.FilenameUtils.getName(...)
- pattern: org.apache.commons.io.FilenameUtils.getBaseName(...)
- id: kotlin_file_rule-FileUploadFileName
languages:
- kotlin
message: 'The filename provided by the FileUpload API can be tampered with by the
client to reference
unauthorized files. The provided filename should be properly validated to ensure
it''s properly
structured, contains no unauthorized path characters (e.g., / \), and refers to
an authorized
file.
'
metadata:
category: security
cwe: CWE-22
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: CRITICAL
severity: ERROR
pattern-either:
- patterns:
- pattern-inside: "$FILES = ($SFU: ServletFileUpload).parseRequest(($REQ: $X.servlet.http.HttpServletRequest?))\n\
...\nfor($ITEM in $FILES) {\n ...\n}\n"
- pattern: $ITEM.getName()
- pattern: '($PART: $X.servlet.http.Part).getSubmittedFileName()'
- id: kotlin_inject_rule-FileDisclosure
languages:
- kotlin
message: 'Constructing a server-side redirect path with user input could allow an
attacker to download application binaries (including application classes or
jar files) or view arbitrary files within protected directories.
'
metadata:
shortDescription: Files or directories accessible to external parties
category: security
cwe: CWE-552
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
mode: taint
pattern-sinks:
- patterns:
- pattern: org.springframework.web.servlet.ModelAndView($FST);
- pattern: $FST
- patterns:
- pattern: org.springframework.web.servlet.ModelAndView($FST, $SND);
- pattern: $FST
- patterns:
- pattern: org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD);
- pattern: $FST
- patterns:
- pattern: org.apache.struts.action.ActionForward($FST)
- pattern: $FST
- patterns:
- pattern: org.apache.struts.action.ActionForward($FST, $SND)
- pattern: $FST
- patterns:
- pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD)
- pattern: $SND
- patterns:
- pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD)
- pattern: $TRD
- patterns:
- pattern-inside: '$ACTION = org.apache.struts.action.ActionForward();
...
'
- pattern: $ACTION.setPath(...)
- patterns:
- pattern-inside: '$MVC = org.springframework.web.servlet.ModelAndView();
...
'
- pattern: $MVC.setViewName(...);
- patterns:
- pattern-inside: '$REQ = $HTTP.getRequestDispatcher(...);
...
'
- pattern-either:
- pattern: $REQ.include($FST, $SND)
- pattern: $REQ.forward($FST, $SND)
pattern-sources:
- pattern: '($VAR: javax.servlet.http.HttpServletRequest).getParameter(...)'
- id: kotlin_inject_rule-SqlInjection
languages:
- kotlin
message: 'The input values included in SQL queries need to be passed in safely.
Bind
variables in prepared statements can be used to easily mitigate the risk of
SQL injection.
'
options:
taint_assume_safe_functions: true
metadata:
shortDescription: Improper Neutralization of Special Elements used in an SQL Command
('SQL Injection')
category: security
cwe: CWE-89
technology:
- java
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern-inside: 'fun $FUNC(..., $SRC: String, ...) { ... }'
- pattern: $SRC
pattern-propagators:
- pattern: $SB.append($SRC)
from: $SRC
to: $SB
- patterns:
- pattern: $F(..., $SRC, ...)
- focus-metavariable: $F
- pattern-either:
- pattern: String.format
- pattern: StringBuilder
from: $SRC
to: $F
pattern-sinks:
- patterns:
- pattern-either:
- pattern: '($PM: javax.jdo.PersistenceManager).newQuery($ARG)'
- pattern: '($PM: javax.jdo.PersistenceManager).newQuery(..., $ARG)'
- pattern: '($Q: javax.jdo.Query).setFilter($ARG)'
- pattern: '($Q: javax.jdo.Query).setGrouping($ARG)'
- pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...)
- pattern: '($S: org.hibernate.Session).createQuery($ARG, ...)'
- pattern: '($S: org.hibernate.Session).createSQLQuery($ARG, ...)'
- pattern: '($S: java.sql.Statement).executeQuery($ARG, ...)'
- pattern: '($S: java.sql.Statement).execute($ARG, ...)'
- pattern: '($S: java.sql.Statement).executeUpdate($ARG, ...)'
- pattern: '($S: java.sql.Statement).executeLargeUpdate($ARG, ...)'
- pattern: '($S: java.sql.Statement).addBatch($ARG, ...)'
- pattern: '($S: java.sql.PreparedStatement).executeQuery($ARG, ...)'
- pattern: '($S: java.sql.PreparedStatement).execute($ARG, ...)'
- pattern: '($S: java.sql.PreparedStatement).executeUpdate($ARG, ...)'
- pattern: '($S: java.sql.PreparedStatement).executeLargeUpdate($ARG, ...)'
- pattern: '($S: java.sql.PreparedStatement).addBatch($ARG, ...)'
- pattern: '($S: java.sql.Connection).prepareCall($ARG, ...)'
- pattern: '($S: java.sql.Connection).prepareStatement($ARG, ...)'
- pattern: '($S: java.sql.Connection).nativeSQL($ARG, ...)'
- pattern: org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG,
...)
- pattern: '($F: org.springframework.jdbc.core.PreparedStatementCreatorFactory).newPreparedStatementCreator($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).execute($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).query($ARG, ...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcOperations).update($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).execute($ARG, ...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).query($ARG, ...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong($ARG,
...)'
- pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).update($ARG, ...)'
- pattern: '($O: io.vertx.sqlclient.SqlClient).query($ARG, ...)'
- pattern: '($O: io.vertx.sqlclient.SqlClient).preparedQuery($ARG, ...)'
- pattern: '($O: io.vertx.sqlclient.SqlConnection).prepare($ARG, ...)'
- pattern: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery($ARG, ...)'
- pattern: '($O: org.apache.torque.util.BasePeer).executeQuery($ARG, ...)'
- pattern: '($O: javax.persistence.EntityManager).createQuery($ARG, ...)'
- pattern: '($O: javax.persistence.EntityManager).createNativeQuery($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).createQuery($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).createScript($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).createUpdate($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).execute($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).prepareBatch($ARG, ...)'
- pattern: '($H: org.jdbi.v3.core.Handle).select($ARG, ...)'
- pattern: org.jdbi.v3.core.statement.Script($H, $ARG)
- pattern: org.jdbi.v3.core.statement.Update($H, $ARG)
- pattern: org.jdbi.v3.core.statement.PreparedBatch($H, $ARG)
- focus-metavariable: $ARG
- id: kotlin_inject_rule-OgnlInjection
message: '"A expression is built with a dynamic value. The source of the value(s)
should be verified to
avoid that unfiltered values fall into this risky code evaluation."
'
languages:
- kotlin
severity: WARNING
metadata:
shortDescription: Expression injection (OGNL)
category: security
cwe: CWE-917
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern-either:
- pattern-inside: "fun $FUNC(..., $VAR: String, ...) {\n ...\n}\n"
- pattern-inside: "fun $FUNC(..., $VAR: Map<$K,$V>, ...) {\n ...\n}\n"
- pattern-inside: "fun $FUNC(..., $VAR: Map<$K,*>, ...) {\n ...\n}\n"
- pattern-inside: "fun $FUNC(..., $VAR: java.util.HashMap<$K,$V>, ...) {\n ...\n\
}\n"
- pattern-either:
- pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables(...,$VAR,
...)
- pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection(...,
$VAR, ...)
- pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(..., $VAR,
...)
- pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.TextParser).evaluate(..., $VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.OgnlTextParser).evaluate(..., $VAR,
...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getGetMethod(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getSetMethod(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getField(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperties(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperty(...,$VAR,
...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getValue(...,$VAR,
...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setValue(...,$VAR,
...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getGetMethod(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getSetMethod(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getField(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperties(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperty(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getValue(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setValue(...,
$VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperties(..., $VAR,
...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperty(..., $VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).getValue(..., $VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setValue(..., $VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).callMethod(..., $VAR, ...)
- pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).compile(..., $VAR, ...)
- pattern: ($P:org.apache.struts2.util.VelocityStrutsUtil).evaluate(...)
- pattern: org.apache.struts2.util.StrutsUtil.findString(...)
- pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL)
- pattern: org.apache.struts2.util.StrutsUtil.getText(...)
- pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...)
- pattern: org.apache.struts2.util.StrutsUtil.makeSelectList(..., $VAR, ...)
- pattern: ($T:org.apache.struts2.views.jsp.ui.OgnlTool).findValue(..., $VAR,
...)
- pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findString(...)
- pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findValue(..., $VAR, ...)
- pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setValue(..., $VAR, ...)
- pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setParameter(..., $VAR,
...)
- id: kotlin_inject_rule-CommandInjection
languages:
- kotlin
message: 'The highlighted API is used to execute a system command. If unfiltered
input is passed to this
API, it can lead to arbitrary command execution.
'
severity: WARNING
metadata:
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
category: security
cwe: CWE-78
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
pattern-either:
- patterns:
- pattern-inside: "fun $FUNC(..., $PARAM: String, ...) {\n ...\n}\n"
- pattern-inside: '$R = Runtime.getRuntime()
...
'
- pattern-either:
- pattern: $R.exec(<...$PARAM...>,...)
- patterns:
- pattern-either:
- pattern: '$CMDARR = arrayOf("$SHELL",...,<...$PARAM...>,...)
...
$R.exec($CMDARR,...)
'
- pattern: $R.exec(arrayOf("$SHELL",...,<...$PARAM...>,...), ...)
- pattern: $R.exec(java.util.String.format("...", ...,<...$PARAM...>,...))
- pattern: '$R.exec(($A: String) + ($B: String))'
- metavariable-regex:
metavariable: $SHELL
regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$
- pattern-not: $R.exec("...","...","...",...)
- pattern-not: '$R.exec(arrayOf("...","...","...",...),...)
'
- patterns:
- pattern-inside: "fun $FUNC(..., $PARAM: String, ...) {\n ...\n}\n"
- pattern-inside: '$PB = ProcessBuilder()
...
'
- pattern-either:
- pattern: $PB.command(<...$PARAM...>,...)
- patterns:
- pattern-inside: $VAL = <...$PARAM...>; ...
- pattern: $PB.command(<...$VAL...>,...)
- patterns:
- pattern-either:
- pattern: $PB.command("$SHELL",...,<...$PARAM...>,...)
- pattern: '$CMDARR = java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...)
...
$PB.command($CMDARR,...)
'
- pattern: $PB.command(java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...),...)
- pattern: $PB.command(java.util.String.format("...", ...,<...$PARAM...>,...))
- pattern: '$PB.command(($A: String) + ($B: String))'
- metavariable-regex:
metavariable: $SHELL
regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$
- pattern-not: $PB.command("...","...","...",...)
- pattern-not: '$PB.command(java.util.Arrays.asList("...","...","...",...))
'
- id: kotlin_inject_rule-SpotbugsPathTraversalAbsolute
languages:
- kotlin
message: 'The software uses an HTTP request parameter to construct a pathname that
should be within a
restricted directory, but it does not properly neutralize absolute path sequences
such as
"/abs/path" that can resolve to a location that is outside of that directory.
See
http://cwe.mitre.org/data/definitions/36.html for more information.
'
severity: WARNING
metadata:
shortDescription: Improper limitation of a pathname to a restricted directory
('Path Traversal')
category: security
cwe: CWE-22
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
mode: taint
pattern-sanitizers:
- pattern: org.apache.commons.io.FilenameUtils.getName(...)
pattern-sinks:
- patterns:
- pattern-inside: '$U = java.net.URI($VAR)
'
- pattern-either:
- pattern-inside: java.io.File($U)
- pattern-inside: java.nio.file.Paths.get($U)
- pattern: $VAR
- patterns:
- pattern-inside: java.io.RandomAccessFile($INPUT,...)
- pattern: $INPUT
- pattern: java.io.FileReader(...)
- pattern: javax.activation.FileDataSource(...)
- pattern: java.io.FileInputStream(...)
- pattern: java.io.File(...)
- pattern: java.nio.file.Paths.get(...)
- pattern: java.io.File.createTempFile(...)
- pattern: java.io.File.createTempDirectory(...)
- pattern: java.nio.file.Files.createTempFile(...)
- pattern: java.nio.file.Files.createTempDirectory(...)
- patterns:
- pattern: $SRC.$METHOD(...)
- metavariable-pattern:
metavariable: $SRC
pattern-either:
- pattern: getClass()
- pattern: getClass().getClassLoader()
- pattern: '($C: ClassLoader)'
- pattern: '($C: Class)'
- pattern: $CLZ.getClassLoader()
- metavariable-pattern:
metavariable: $METHOD
pattern-either:
- pattern: getResourceAsStream
- pattern: getResource
- patterns:
- pattern-inside: java.io.FileWriter($PATH, ...)
- pattern: $PATH
- patterns:
- pattern-inside: java.io.FileOutputStream($PATH, ...)
- pattern: $PATH
pattern-sources:
- pattern: '($REQ: HttpServletRequest).getParameter(...)'
- patterns:
- pattern-inside: fun $FUNC(..., @RequestParam $REQ:$TYPE, ...) {...}
- focus-metavariable: $REQ
- id: kotlin_inject_rule-HttpParameterPollution
languages:
- kotlin
message: 'Concatenating unvalidated user input into a URL can allow an attacker
to override the value of
a request parameter. Attacker may be able to override existing parameter values,
inject a new
parameter or exploit variables out of a direct reach. HTTP Parameter Pollution
(HPP) attacks
consist of injecting encoded query string delimiters into other existing parameters.
If a web
application does not properly sanitize the user input, a malicious user may compromise
the
logic of the application to perform either client-side or server-side attacks.
'
severity: ERROR
metadata:
shortDescription: Improper neutralization of argument delimiters in a command
('Argument Injection')
category: security
cwe: CWE-88
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: CRITICAL
mode: taint
pattern-sources:
- pattern: '($REQ: HttpServletRequest).getParameter(...)'
pattern-sanitizers:
- pattern: java.net.URLEncoder.encode(...)
- pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...)
pattern-sinks:
- pattern: org.apache.http.client.methods.HttpGet(...)
- pattern: org.apache.commons.httpclient.methods.GetMethod(...)
- pattern: '($GM: org.apache.commons.httpclient.methods.GetMethod).setQueryString(...)'
- id: kotlin_inject_rule-LDAPInjection
languages:
- kotlin
message: 'Just like SQL, all inputs passed to an LDAP query need to be passed in
safely. Unfortunately,
LDAP doesn''t have prepared statement interfaces like SQL. Therefore, the primary
defense
against LDAP injection is strong input validation of any untrusted data before
including it in
an LDAP query.
'
severity: WARNING
metadata:
shortDescription: Improper neutralization of special elements used in an LDAP
query ('LDAP Injection')
category: security
cwe: CWE-90
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
mode: taint
pattern-sinks:
- pattern: javax.naming.ldap.LdapName(...)
- pattern: '($C: javax.naming.directory.Context).lookup(...)'
- pattern: '($C: javax.naming.Context).lookup(...)'
- patterns:
- pattern-inside: '($C: com.unboundid.ldap.sdk.LDAPConnection).search($QUERY,
...)'
- pattern: $QUERY
- patterns:
- pattern-either:
- patterns:
- pattern-either:
- pattern: $CTX.lookup(...)
- patterns:
- pattern-inside: $CTX.search($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($NAME, $FILTER, ...)
- pattern: $FILTER
- metavariable-pattern:
metavariable: $CTX
pattern-either:
- pattern: '($C: DirContext)'
- pattern: '($IDC: InitialDirContext)'
- pattern: '($LC: LdapContext)'
- pattern: '($EDC: EventDirContext)'
- pattern: '($LC: LdapCtx)'
- pattern: '($C: javax.naming.directory.DirContext)'
- pattern: '($IDC: javax.naming.directory.InitialDirContext)'
- pattern: '($LC: javax.naming.ldap.LdapContext)'
- pattern: '($EDC: javax.naming.event.EventDirContext)'
- pattern: '($LC: com.sun.jndi.ldap.LdapCtx)'
- patterns:
- pattern-either:
- pattern: $CTX.lookup(...)
- patterns:
- pattern-inside: $CTX.search($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($NAME, $FILTER, ...)
- pattern: $FILTER
- pattern-inside:
pattern-either:
- pattern: $CTX = DirContext(...);...
- pattern: $CTX = InitialDirContext(...);...
- pattern: $CTX = LdapContext(...);...
- pattern: $CTX = EventDirContext(...);...
- pattern: $CTX = LdapCtx(...);...
- pattern: $CTX = javax.naming.directory.DirContext(...);...
- pattern: $CTX = javax.naming.directory.InitialDirContext(...);...
- pattern: $CTX = javax.naming.ldap.LdapContext(...);...
- pattern: $CTX = javax.naming.event.EventDirContext(...);...
- pattern: $CTX = com.sun.jndi.ldap.LdapCtx(...);...
- pattern-either:
- patterns:
- pattern-either:
- patterns:
- pattern-inside: $CTX.list($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.lookup($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($NAME, $FILTER, ...)
- pattern: $FILTER
- metavariable-pattern:
metavariable: $CTX
pattern-either:
- pattern: '($LT: LdapTemplate)'
- pattern: '($LO: LdapOperations)'
- pattern: '($LT: org.springframework.ldap.core.LdapTemplate)'
- pattern: '($LO: org.springframework.ldap.core.LdapOperations)'
- patterns:
- pattern-either:
- patterns:
- pattern-inside: $CTX.list($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.lookup($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($QUERY, ...)
- pattern: $QUERY
- patterns:
- pattern-inside: $CTX.search($NAME, $FILTER, ...)
- pattern: $FILTER
- pattern-inside:
pattern-either:
- pattern: $CTX = LdapTemplate(...);...
- pattern: $CTX = LdapOperations(...);...
- pattern: $CTX = org.springframework.ldap.core.LdapTemplate(...);...
- pattern: $CTX = org.springframework.ldap.core.LdapOperations(...);...
pattern-sources:
- patterns:
- pattern-inside: "fun $FUNC(..., $VAR: String, ...) {\n ...\n}\n"
- pattern: $VAR
- patterns:
- pattern-inside: "fun $FUNC(..., $X: String, ...) {\n ...\n $VAR = ... + $X\n\
\ ...\n}\n"
- pattern: $VAR
- id: kotlin_inject_rule-ELInjection
languages:
- kotlin
message: 'An expression is built with a dynamic value. The source of the value(s)
should be verified to
avoid that unfiltered values fall into this risky code evaluation.
'
metadata:
category: security
cwe: CWE-917
shortDescription: Improper neutralization of special elements used in an expression
language statement ('Expression Language Injection')
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
severity: WARNING
pattern-either:
- patterns:
- metavariable-regex:
metavariable: $METHOD
regex: ^create(Method|Value)Expression$
- metavariable-pattern:
metavariable: $EXPR
patterns:
- pattern-not: '"..."'
- pattern: '($EXP: ExpressionFactory ).$METHOD(($CTX: $X.el.ELContext), $EXPR,
...)
'
- patterns:
- pattern: '($P: $X.el.ELProcessor).$METHOD(...)
'
- pattern-not: '($P: $X.el.ELProcessor).$METHOD("...", ...)
'
- metavariable-regex:
metavariable: $METHOD
regex: ^(eval|(get|set)Value)$
- id: kotlin_perm_rule-DangerousPermissions
languages:
- kotlin
message: 'Do not grant dangerous combinations of permissions.
'
metadata:
shortDescription: Insecure inherited permissions
category: security
cwe: CWE-277
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
confidence: HIGH
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- patterns:
- pattern-inside: '$PC = $X.getPermissions(...)
...
'
- pattern: $PC.add($PERMISSION)
- pattern: '$REFVAR = $PERMISSION
...;
($PC: PermissionCollection).add($REFVAR)
'
- pattern: '($PC: PermissionCollection).add($PERMISSION)'
- metavariable-pattern:
metavariable: $PERMISSION
pattern-either:
- pattern: ReflectPermission("suppressAccessChecks")
- pattern: RuntimePermission("createClassLoader")
- id: kotlin_perm_rule-OverlyPermissiveFilePermissionInline
languages:
- kotlin
message: 'Overly permissive file permission
'
metadata:
shortDescription: Incorrect permission assignment for critical resource
cwe: CWE-732
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
category: security
confidence: HIGH
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"));
- pattern: '$PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING");
...
java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS);
'
- metavariable-regex:
metavariable: $PERM_STRING
regex: '[rwx-]{6}[rwx]{1,}'
- id: kotlin_ldap_rule-AnonymousLDAP
languages:
- kotlin
message: 'Without proper access control, executing an LDAP statement that contains
a
user-controlled value can allow an attacker to abuse poorly configured LDAP
context
'
metadata:
shortDescription: Missing authentication for critical function (LDAP)
category: security
cwe: CWE-306
owasp:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-inside: 'import javax.naming.Context
...
'
- pattern: $ENV[Context.SECURITY_AUTHENTICATION] = "none"
- id: rules_lgpl_kotlin_other_rule-android-kotlin-webview-debug
patterns:
- pattern: '$X.setWebContentsDebuggingEnabled(true)
'
- pattern-inside: 'WebView
...
'
message: "Remote WebView debugging is enabled.This can introduce security \nrisks\
\ as it allows remote debugging tools, such as Chrome DevTools, \nto inspect and\
\ manipulate the WebView content. This can potentially \nexpose sensitive information,\
\ including user data, session tokens, \nand other confidential data, to unauthorized\
\ parties.\n\nTo fix this security issue, you should disable remote WebView \n\
debugging in production builds of your app. Here's how you can do it:\n```\nimport\
\ WebKit\n\nclass ViewController: UIViewController {\n\n override func viewDidLoad()\
\ {\n super.viewDidLoad()\n\n // Disable remote WebView debugging\
\ in production builds\n #if DEBUG\n WebViewConfiguration.shared().preferences.setValue(true,\
\ forKey: \"developerExtrasEnabled\")\n #else\n WebViewConfiguration.shared().preferences.setValue(false,\
\ forKey: \"developerExtrasEnabled\")\n #endif\n\n // Other setup\
\ code...\n }\n\n // Other methods...\n}\n```\n"
languages:
- kotlin
severity: WARNING
metadata:
category: security
cwe: CWE-489
shortDescription: Leftover debug code
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
- id: kotlin_xss_rule-WicketXSS
languages:
- kotlin
message: 'Disabling HTML escaping put the application at risk for Cross-Site Scripting
(XSS).
'
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-inside: 'import org.apache.wicket.$A
...
'
- pattern: '$OBJ.setEscapeModelStrings(false);
'
- id: kotlin_xss_rule-XSSReqParamToServletWriter
languages:
- kotlin
message: 'Servlet reflected cross site scripting vulnerability
'
severity: WARNING
metadata:
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
category: security
cwe: CWE-79
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
mode: taint
pattern-sanitizers:
- patterns:
- pattern-inside: org.owasp.encoder.Encode.forHtml($TAINTED);
- pattern: $TAINTED
pattern-sinks:
- patterns:
- pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}'
- pattern-inside: '$WRITER = $RES.getWriter();
...
'
- pattern: $WRITER.write($DATA,...);
- pattern: $DATA
- patterns:
- pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}'
- pattern: $RES.getWriter().write($DATA,...);
- pattern: $DATA
pattern-sources:
- patterns:
- pattern-inside: 'fun $FUNC(..., $REQ: HttpServletRequest , ...) {...}'
- pattern: $REQ.getParameter(...);
- id: kotlin_script_rule-ScriptInjection
languages:
- kotlin
message: 'The software constructs all or part of a code segment using externally-influenced
input from an upstream component, but it does not neutralize or incorrectly
neutralizes special elements that could modify the syntax or behavior of the
intended code segment.
'
severity: ERROR
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
mode: taint
pattern-sinks:
- patterns:
- patterns:
- pattern-inside: '$ENGINE = $F.getEngineByExtension(...)
...
'
- pattern: $ENGINE.eval($ARG, ...);
- pattern-not: $ENGINE.eval("...");
- pattern-not: '$ENGINE.eval("...", ($BINDING: javax.script.Bindings));'
- patterns:
- pattern: '($ENGINE: javax.script.ScriptEngine).eval($ARG, ...);'
- pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...");'
- pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...", ($BINDING: javax.script.Bindings));'
- pattern: '($INVC: javax.script.Invocable).invokeFunction(..., $ARG)'
- pattern: '($INVC: javax.script.Invocable).invokeMethod(..., $ARG)'
pattern-sources:
- patterns:
- pattern-inside: 'fun $FUNC(..., $VAR: String, ...) { ... }'
- pattern: $VAR
- id: kotlin_xml_rule-SAMLIgnoreComments
languages:
- kotlin
message: 'Ignoring XML comments in SAML may lead to authentication bypass
'
metadata:
shortDescription: Weak authentication
cwe: CWE-1390
category: security
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
severity: WARNING
pattern: '($POOL: org.opensaml.xml.parse.BasicParserPool).setIgnoreComments(false);'
- id: kotlin_xml_rule-XsltTransform
languages:
- kotlin
message: 'It is possible to attach malicious behavior to those style sheets. Therefore,
if an attacker
can control the content or the source of the style sheet, he might be able to
trigger remote
code execution.
'
metadata:
shortDescription: XML injection (aka Blind XPath injection)
category: security
cwe: CWE-91
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: MEDIUM
severity: WARNING
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- patterns:
- pattern-inside: "fun $FUNC(...,$VAR: String, ...) {\n ...\n}\n"
- pattern-either:
- pattern: FileInputStream(<... $VAR ...>);
- pattern: javaClass.getResourceAsStream(<... $VAR ...>)
- patterns:
- pattern-inside: "class $CLZ {\n var $X = \"...\";\n ...\n}\n"
- pattern-inside: "fun $FUNC(...,$Y: String, ...) {\n ...\n}\n"
- pattern-either:
- pattern: FileInputStream($X + $Y);
- pattern: javaClass.getResourceAsStream($X + $Y)
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: '($T: javax.xml.transform.TransformerFactory).newTransformer($SRC,
...)'
- pattern-inside: '($T: javax.xml.transform.Transformer).transform($SRC, ...)'
- patterns:
- pattern-inside: '$FACTORY = javax.xml.transform.TransformerFactory.newInstance(...)
...'
- pattern-inside: $FACTORY.newTransformer($SRC, ...)
- patterns:
- pattern-inside: '$FACTORY = javax.xml.transform.TransformerFactory(...)
...'
- pattern-inside: '$T = $FACTORY.newTransformer(...)
...'
- pattern-inside: $T.transform($SRC, ...)
- pattern: $SRC
- id: kotlin_xml_rule-XmlDecoder
languages:
- kotlin
message: 'Avoid using XMLDecoder to parse content from an untrusted source.
'
metadata:
shortDescription: Deserialization of untrusted data
category: security
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- pattern: '($D: java.beans.XMLDecoder).readObject()'
- patterns:
- pattern: $D.readObject()
- pattern-inside: '$D = XMLDecoder(...)
...
'
- pattern-not:
pattern-either:
- patterns:
- pattern-inside: '$DEC = java.beans.XMLDecoder(..., $CL)
...
'
- pattern: $DEC.readObject()
- metavariable-pattern:
metavariable: $CL
patterns:
- pattern: "object : ClassLoader() {\n ...\n fun loadClass(name: String,\
\ resolve: Boolean): $RET {\n if($X){\n throw ...\n }\n\
\ ...\n }\n ...\n}\n"
- metavariable-pattern:
metavariable: $X
pattern-either:
- pattern: 'name != ...
'
- pattern: '!$LIST.contains(name)
'
- patterns:
- pattern-inside: '$CLASS_LOADER = $CL
...
'
- pattern-inside: '$DEC = java.beans.XMLDecoder(..., $CLASS_LOADER)
...
'
- pattern: $DEC.readObject()
- metavariable-pattern:
metavariable: $CL
patterns:
- pattern: "object : ClassLoader(){\n ...\n fun loadClass(name: String,\
\ resolve: Boolean): $RET{\n if($X){\n throw ...\n }\n\
\ ...\n }\n ...\n}\n"
- metavariable-pattern:
metavariable: $X
pattern-either:
- pattern: 'name != ...
'
- pattern: '!$LIST.contains(name)
'
- id: kotlin_csrf_rule-SpringCSRFDisabled
languages:
- kotlin
message: 'The application fails to protect against Cross-Site Request Forgery (CSRF)
due to disabling Spring''s CSRF protection features.
'
metadata:
shortDescription: Cross-Site Request Forgery (CSRF)
category: security
cwe: CWE-352
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
severity: WARNING
pattern-either:
- pattern: '($H: org.springframework.security.config.annotation.web.builders.HttpSecurity).
... .csrf().disable()'
- pattern: '($C: CsrfConfigurer<HttpSecurity>).disable()'
- id: kotlin_xpathi_rule-XpathInjection
languages:
- kotlin
message: 'The input values included in SQL queries need to be passed in safely.
Bind
variables in prepared statements can be used to easily mitigate the risk of
SQL injection.
'
metadata:
shortDescription: Improper neutralization of data within XPath expressions ('XPath
Injection')
category: security
cwe: CWE-643
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern-inside: "fun $FUNC(..., $VAR: $T, ...) {\n ...\n}\n"
- pattern: $VAR
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: "import javax.xml.xpath.*; \n...\n"
- pattern-inside: "import javax.xml.xpath.XPath; \n...\n"
- patterns:
- pattern-either:
- patterns:
- pattern: $X.compile($VAR)
- pattern-not: $X.compile("...")
- patterns:
- pattern: $X.evaluate($VAR, ...)
- pattern-not: $X.evaluate("...", ...)
pattern-sanitizers:
- pattern-either:
- pattern-inside: '$X.xPathVariableResolver = ...;
...;
$X.compile("...");
'
- pattern-inside: '$X.setXPathVariableResolver(...);
...;
$X.compile("...");
'
- id: kotlin_unsafe_rule-ExternalConfigControl
languages:
- kotlin
message: 'Allowing external control of system settings can disrupt service or cause
an application to
behave in unexpected, and potentially malicious ways. An attacker could cause
an error by
providing a nonexistent catalog name or connect to an unauthorized portion of
the database.
'
severity: WARNING
metadata:
shortDescription: External control of system or configuration setting
category: security
cwe: CWE-15
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
patterns:
- metavariable-pattern:
metavariable: $GET_PARAMETER
pattern-either:
- pattern: '($REQ: HttpServletRequest).getParameter'
- pattern: '($REQ: HttpServletRequest?)?.getParameter'
- metavariable-pattern:
metavariable: $SET_CATALOG
pattern-either:
- pattern: '($CONN: java.sql.Connection).setCatalog'
- pattern: '($CONN: java.sql.Connection?)?.setCatalog'
- pattern: '$TAINTED = $GET_PARAMETER(...)
...
$SET_CATALOG($TAINTED)'
- id: kotlin_smtp_rule-InsecureSmtp
languages:
- kotlin
message: 'Server identity verification is disabled when making SSL connections.
'
metadata:
shortDescription: Improper validation of certificate with host mismatch
category: security
cwe: CWE-297
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-either:
- pattern-inside: '$E = org.apache.commons.mail.SimpleEmail(...)
...
'
- pattern-inside: '$E = org.apache.commons.mail.Email(...)
...
'
- pattern-inside: '$E = org.apache.commons.mail.MultiPartEmail(...)
...
'
- pattern-inside: '$E = org.apache.commons.mail.HtmlEmail(...)
...
'
- pattern-inside: '$E = org.apache.commons.mail.ImageHtmlEmail(...)
...
'
- pattern-not: '$E.setSSLOnConnect(true)
...
$E.setSSLCheckServerIdentity(true)
'
- id: kotlin_smtp_rule-SmtpClient
languages:
- kotlin
message: 'Simple Mail Transfer Protocol (SMTP) is a the text based protocol used
for
email delivery. Like with HTTP, headers are separate by new line separator. If
kuser input is place in a header line, the application should remove or replace
new line characters (CR / LF). You should use a safe wrapper such as Apache
Common Email and Simple Java Mail which filter special characters that can lead
to header injection.
'
metadata:
shortDescription: Improper neutralization of special elements used in a command
category: security
cwe: CWE-77
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
severity: ERROR
patterns:
- pattern-inside: '$M = MimeMessage(...);
...
'
- pattern-either:
- patterns:
- pattern-either:
- pattern: $M.setSubject($VAR)
- pattern: $M.addHeader($ARG, $VAR)
- pattern: $M.addHeader($VAR, $ARG)
- pattern: $M.setDescription($VAR)
- pattern: $M.setDisposition($VAR)
- metavariable-regex:
metavariable: $VAR
regex: ^[a-zA-Z_$][a-zA-Z0-9_$]*$
- patterns:
- pattern-either:
- pattern: $M.setSubject($OBJ.$GETTER(...))
- pattern: $M.setSubject($OBJ.$GETTER(...) + ...)
- pattern: $M.setSubject(... + $OBJ.$GETTER(...))
- pattern: $M.setSubject(... + $OBJ.$GETTER(...) + ...)
- pattern: $M.addHeader($ARG, $OBJ.$GETTER(...))
- pattern: $M.addHeader($ARG, $OBJ.$GETTER(...) + ...)
- pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...))
- pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...) + ...)
- pattern: $M.addHeader($OBJ.$GETTER(...), $ARG)
- pattern: $M.addHeader($OBJ.$GETTER(...) + ..., $ARG)
- pattern: $M.addHeader(... + $OBJ.$GETTER(...), $ARG)
- pattern: $M.addHeader(... + $OBJ.$GETTER(...) + ..., $ARG)
- pattern: $M.setDescription($OBJ.$GETTER(...))
- pattern: $M.setDisposition($OBJ.$GETTER(...) + ...)
- pattern: $M.setDisposition(... + $OBJ.$GETTER(...))
- pattern: $M.setDisposition(... + $OBJ.$GETTER(...) + ...)
- metavariable-regex:
metavariable: $GETTER
regex: ^get
- id: kotlin_endpoint_rule-WeakHostNameVerification
languages:
- kotlin
message: 'A HostnameVerifier that accept any host are often use because of certificate
reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle
attacks since the client will trust any certificate.
'
metadata:
category: security
cwe: CWE-295
shortDescription: Improper Certificate Validation
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern-either:
- patterns:
- pattern-inside: "class $V : HostnameVerifier {\n ...\n}\n"
- pattern: "fun verify(...): Boolean {\n return true\n}\n"
- patterns:
- pattern-inside: "class $V : X509TrustManager {\n ...\n}\n"
- pattern-either:
- pattern: fun checkClientTrusted(...) {}
- pattern: fun checkServerTrusted(...) {}
- pattern: 'fun getAcceptedIssuers(): Array<X509Certificate>? {return null}'
- id: kotlin_endpoint_rule-UnvalidatedRedirect
languages:
- kotlin
message: 'Unvalidated redirects occur when an application redirects a user to a
destination URL specified by a user supplied parameter that is not validated.
Such vulnerabilities can be used to facilitate phishing attacks.
'
metadata:
category: security
cwe: CWE-601
owasp:
- A1:2017-Injection
- A03:2021-Injection
shortDescription: URL redirection to untrusted site ('Open Redirect')
security-severity: CRITICAL
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern: '$URL = ($REQ: $X.servlet.http.HttpServletRequest).$M(...);
'
- metavariable-regex:
metavariable: $M
regex: (getParameter|getCookies|getHeader|getHeaders|getHeaderNames|getPathInfo|getPathTranslated|getContextPath|getQueryString|getRemoteUser|getRequestedSessionId|getRequestURI|getRequestURL|getServletPath|getParts|getPart|getReader)
pattern-sinks:
- pattern-either:
- pattern: '($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL)
'
- pattern: '($RES: $X.servlet.http.HttpServletResponse).addHeader("Location",
$URL)
'
pattern-sanitizers:
- patterns:
- pattern-inside: "if ($SAFE.contains($URL)){\n ...\n}\n"
- pattern-either:
- pattern: '($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL)
'
- pattern: '($RES: $X.servlet.http.HttpServletResponse).addHeader("Location",
$URL)
'
- id: kotlin_cors_rule-PermissiveCORSInjection
languages:
- kotlin
message: 'Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures
that in order for
JavaScript to access the contents of a Web page, both the JavaScript and the Web
page must
originate from the same domain. Without the Same Origin Policy, a malicious website
could serve
up JavaScript that loads sensitive information from other websites using a client''s
credentials, cull through it, and communicate it back to the attacker. HTML5 makes
it possible
for JavaScript to access data across domains if a new HTTP header called
Access-Control-Allow-Origin is defined. With this header, a Web server defines
which other
domains are allowed to access its domain using cross-origin requests. However,
caution should
be taken when defining the header because an overly permissive CORS policy will
allow a
malicious application to communicate with the victim application in an inappropriate
way,
leading to spoofing, data theft, relay and other attacks.
'
severity: ERROR
metadata:
shortDescription: Permissive cross-domain policy with untrusted domains
cwe: CWE-942
category: security
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: CRITICAL
mode: taint
pattern-sources:
- pattern: '($REQ: HttpServletRequest).getParameter(...)'
- pattern: '($REQ: HttpServletRequest).getHeader(...)'
- pattern: '($REQ: HttpServletRequest).getPathInfo()'
- pattern: '($REQ: HttpServletRequest).getQueryString()'
- pattern: '($REQ: HttpServletRequest).getAttribute(...)'
- pattern: '($REQ: HttpServletRequest).getSession().getAttribute(...)'
- pattern: '($REQ: HttpServletRequest).getServletContext().getAttribute(...)'
- pattern: '($REQ: HttpServletRequest).getParameterValues(...)'
- pattern: '($REQ: HttpServletRequest).getParameterNames()'
- pattern: '($REQ: HttpServletRequest).getParameterMap()'
pattern-sinks:
- patterns:
- pattern-either:
- pattern: '($RES: HttpServletResponse).setHeader("$HEADER", ...)'
- pattern: '($RES: HttpServletResponse).addHeader("$HEADER", ...)'
- metavariable-regex:
metavariable: $HEADER
regex: (?i)(Access-Control-Allow-Origin)
- id: kotlin_cookie_rule-CookieHTTPOnly
languages:
- kotlin
message: 'A new cookie is created without the HttpOnly flag set. The HttpOnly flag
is a directive to the
browser to make sure that the cookie can not be red by malicious script. When
a user is the
target of a "Cross-Site Scripting", the attacker would benefit greatly from getting
the session
id for example.
'
severity: WARNING
metadata:
shortDescription: Sensitive cookie without 'HttpOnly' flag
category: security
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-1004
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern: '$C = $X.servlet.http.Cookie(..., ...)
...;
($RESP: $X.servlet.http.HttpServletResponse).addCookie($C)
'
- pattern-not-inside: '$C = $X.servlet.http.Cookie(..., ...)
...
$C.setHttpOnly(true)
...;
($RESP: $X.servlet.http.HttpServletResponse).addCookie($C)
'
- id: kotlin_cookie_rule-HttpResponseSplitting
languages:
- kotlin
message: 'When an HTTP request contains unexpected CR and LF characters, the server
may respond with an
output stream that is interpreted as two different HTTP responses (instead of
one). An attacker
can control the second response and mount attacks such as cross-site scripting
and cache
poisoning attacks.
'
severity: WARNING
metadata:
shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP
Response Splitting')
category: security
cwe: CWE-113
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: MEDIUM
mode: taint
pattern-sanitizers:
- patterns:
- metavariable-pattern:
metavariable: $S0
pattern-either:
- pattern: '...'
- pattern: '""'
- metavariable-pattern:
metavariable: $PATTERN
patterns:
- pattern: '...'
- pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+
- pattern-inside: '$STR.replace($PATTERN, $S0)
...
'
- pattern: org.apache.commons.text.StringEscapeUtils.escapeJava(...)
pattern-sinks:
- pattern: javax.servlet.http.Cookie("$KEY", ...)
- patterns:
- pattern-inside: '$C = javax.servlet.http.Cookie("$KEY", ...)
...
'
- pattern: $C.setValue(...)
pattern-sources:
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameter(...)'
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterNames()'
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterValues(...)'
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterMap()'
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getHeader(...)'
- pattern: '($REQ: javax.servlet.http.HttpServletRequest).getPathInfo()'
- id: kotlin_cookie_rule-CookieInsecure
languages:
- kotlin
message: "\"A new cookie is created without the Secure flag set. The Secure flag\
\ is a\n directive to the browser to make sure that the cookie is not sent for\
\ insecure communication\n(http://)\"\n"
severity: WARNING
metadata:
shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute
category: security
cwe: CWE-614
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
technology:
- kotlin
security-severity: MEDIUM
patterns:
- pattern: '$C = $X.servlet.http.Cookie(..., ...)
...;
($RESP: $X.servlet.http.HttpServletResponse).addCookie($C)
'
- pattern-not-inside: '$C = $X.servlet.http.Cookie(..., ...)
...
$C.setSecure(true)
...;
($RESP: $X.servlet.http.HttpServletResponse).addCookie($C)
'
- id: kotlin_cookie_rule-RequestParamToHeader
languages:
- kotlin
message: 'This code directly writes an HTTP parameter to an HTTP header, which allows
for a HTTP
response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting
for
more information.
'
severity: ERROR
metadata:
shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP
Response Splitting')
category: security
cwe: CWE-113
owasp:
- A1:2017-Injection
- A03:2021-Injection
technology:
- kotlin
security-severity: CRITICAL
mode: taint
pattern-sanitizers:
- patterns:
- metavariable-pattern:
metavariable: $S0
pattern-either:
- pattern: '...'
- pattern: '""'
- metavariable-pattern:
metavariable: $PATTERN
patterns:
- pattern: '...'
- pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+
- pattern-inside: '$STR.replace($PATTERN, $S0);
...
'
- pattern: org.apache.commons.text.StringEscapeUtils.unescapeJava(...);
pattern-sinks:
- pattern: '($RES: $X.servlet.http.HttpServletResponse).setHeader("$KEY", ...);'
- pattern: '($RES: $X.servlet.http.HttpServletResponse).addHeader("$KEY", ...);'
- pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).setHeader("$KEY",
...);'
- pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).addHeader("$KEY",
...);'
pattern-sources:
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameter(...);'
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterNames();'
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterValues(...);'
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterMap();'
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getHeader(...);'
- pattern: '($REQ: $X.servlet.http.HttpServletRequest).getPathInfo();'
- id: java_ftp_rule-FTPInsecureTransport
message: "This rule identifies instances where the application uses FTP (File\n\
Transfer Protocol) for transferring files. FTP transmits data in clear\ntext,\
\ allowing usernames, passwords, and other sensitive information to be\nintercepted\
\ by attackers. Consider using secure alternatives like SFTP\n(SSH File Transfer\
\ Protocol) or FTPS (FTP Secure) that provide encryption\nto protect data in transit.\n\
\nRemediation Strategy: To mitigate the risks associated with using unencrypted\n\
FTP, the application should switch to a secure file transfer protocol like\nSFTP\
\ or FTPS. Below is an example of how to implement FTPS in a Java\napplication.\n\
\n``` \nimport org.apache.commons.net.ftp.FTPSClient;\n\npublic class FTPSExample\
\ {\n public static void main(String[] args) {\n String server = \"\
ftps.example.com\";\n int port = 21;\n String user = \"your_username\"\
;\n String pass = \"your_password\";\n\n FTPSClient ftpsClient =\
\ new FTPSClient();\n try {\n ftpsClient.connect(server, port);\n\
\ ftpsClient.login(user, pass);\n // Perform file operations\n\
\n ftpsClient.logout();\n ftpsClient.disconnect();\n \
\ } catch (Exception e) {\n e.printStackTrace();\n }\n \
\ }\n} \n```\n"
severity: WARNING
metadata:
security-severity: MEDIUM
shortDescription: Cleartext transmission of sensitive information
category: security
cwe: CWE-319
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
references:
- https://www.codejava.net/java-se/ftp/connect-and-login-to-a-ftp-server
- https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- java
pattern-either:
- pattern: '(org.apache.commons.net.ftp.FTPClient $FTPCLIENT).connect(...);
'
- pattern: 'URL $URL = new URL("=~/^[fF][tT][pP]://.*/");
...
URLConnection $CONN = $URL.openConnection(...);
'
- id: java_crypto_rule-SpringHTTPRequestRestTemplate
message: "This rule detects instances where Java Spring's RestTemplate API sends\
\ \nrequests to non-secure (http://) URLs. Sending data over HTTP is vulnerable\
\ \nas it does not use TLS encryption, exposing the data to interception, \nmodification,\
\ or redirection by attackers. \n\nTo mitigate this vulnerability, modify the\
\ request URLs to use HTTPS instead, \nwhich ensures that the data is encrypted\
\ during transit and prevents from\nMITM attacks. \n\nSecure Code Example:\n```\n\
public void safe(Object obj) throws Exception {\n RestTemplate restTemplate =\
\ new RestTemplate();\n restTemplate.put(URI.create(\"https://example.com\"),\
\ obj);\n}\n``` \n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map-
- https://www.baeldung.com/rest-template
subcategory:
- vuln
technology:
- spring
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
languages:
- java
mode: taint
pattern-sources:
- pattern: '"=~/^http:\/\/.+/i"
'
pattern-sinks:
- patterns:
- pattern: '(org.springframework.web.client.RestTemplate $RESTTEMP).$FUNC($URL,
...);
'
- focus-metavariable: $URL
- metavariable-regex:
metavariable: $FUNC
regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put|execute)
- id: java_crypto_rule-HttpGetHTTPRequest
languages:
- java
mode: taint
pattern-sources:
- pattern: '"=~/^http:\/\/.+/i"
'
pattern-sinks:
- patterns:
- pattern: '$R = new org.apache.http.client.methods.HttpGet($PROT);
...
$CLIENT. ... .execute($R, ...);
'
- focus-metavariable: $PROT
message: "Detected an HTTP GET request sent via HttpGet. Sending data over HTTP\
\ can\nexpose sensitive information to interception or modification by attackers,\n\
as HTTP does not encrypt the data transmitted. It is critical to use\nHTTPS, which\
\ encrypts the communication, to protect the confidentiality\nand integrity of\
\ data in transit.\n\nTo mitigate the issue, ensure all data transmitted between\
\ the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and\
\ configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement\
\ HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\nSecure\
\ Code Example:\n```\nprivate static void safe() throws IOException {\n HttpGet\
\ httpGet = new HttpGet(\"https://example.com\");\n HttpClients.createDefault().execute(httpGet);\n\
}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
cwe: CWE-319
category: security
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection()
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
- id: java_crypto_rule-GCMNonceReuse
metadata:
shortDescription: Reuse of cryptographic initialization vector
category: security
cwe: CWE-323
technology:
- java
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
languages:
- java
message: "GCM is a mode of operation for symmetric-key cryptographic block ciphers.\
\ GCM allows the usage of\nan initialization vector or nonce used to provide the\
\ initial state. The IV is an arbitrary number \nthat can be used just once in\
\ a cryptographic communication. Re use of initialization vectors \nnullifies\
\ their usage, as the initial state of all GCMs with the same vector will effectively\
\ be\nthe same.\n\nInstead of hard coding an initialization vector, it is recommended\
\ to use nextBytes() method from\njava.security.SecureRandom. This generates a\
\ user specified number of random bytes.\n\nExample using `java.security.SecureRandom`:\n\
```\nCipher cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\nSecretKeySpec\
\ keySpec = new SecretKeySpec(secretKey.getEncoded(), \"AES\");\n\n// Generate\
\ a new, random IV for each encryption operation\nSecureRandom secureRandom =\
\ new SecureRandom();\n// GCM standard recommends a 12-byte (96-bit) IV\nbyte[]\
\ iv = new byte[12];\nsecureRandom.nextBytes(iv);\n\nGCMParameterSpec gcmParameterSpec\
\ = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);\ncipher.init(Cipher.ENCRYPT_MODE,\
\ keySpec, gcmParameterSpec);\n```\n\nFor more information on Java Cryptography\
\ see:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n"
mode: taint
pattern-sources:
- pattern-either:
- pattern: new byte[]{...};
- pattern: $STRING.getBytes();
pattern-sinks:
- pattern: new GCMParameterSpec(...,$NONCE, ...)
severity: WARNING
- id: java_crypto_rule_JwtNoneAlgorithm
message: 'Detected use of the ''none'' algorithm in a JWT token. The ''none''
algorithm assumes the integrity of the token has already been verified.
This would allow a malicious actor to forge a JWT token that will
automatically be verified. Do not explicitly use the ''none'' algorithm.
Instead, use an algorithm such as ''HS256''.
For more information on how to securely use JWT please see OWASP:
- https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html
'
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
asvs:
section: 'V3: Session Management Verification Requirements'
control_id: 3.5.3 Insecue Stateless Session Tokens
control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management
version: '4'
category: security
technology:
- jwt
confidence: LOW
references:
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Cryptographic Issues
security-severity: CRITICAL
languages:
- java
severity: ERROR
pattern-either:
- patterns:
- pattern: 'io.jsonwebtoken.Jwts.builder()
'
- pattern-not-inside: "$RETURNTYPE $FUNC(...) {\n ...\n $JWTS.signWith(...);\n\
\ ...\n}\n"
- pattern: '$J.sign(com.auth0.jwt.algorithms.Algorithm.none())
'
- pattern: 'new com.nimbusds.jose.PlainHeader(...);
'
- pattern: 'new com.nimbusds.jose.PlainHeader.Builder(). ... .build();
'
- id: java_crypto_rule-TelnetRequest
message: "Checks for attempts to connect through telnet. Telnet is an outdated\n\
protocol that transmits all data, including sensitive information like\npasswords,\
\ in clear text. This exposes it to interception and\neavesdropping on unsecured\
\ networks.\n\nTo mitigate this issue, replace Telnet usage with more secure protocols\
\ \nsuch as SSH (Secure Shell), which provides encrypted communication. Use \n\
the SSH functionality provided by libraries like JSch or Apache MINA SSHD \nfor\
\ secure data transmission.\n\nSecure Code Example:\n```\nimport com.jcraft.jsch.JSch;\n\
import com.jcraft.jsch.Session;\n\npublic class SecureConnector {\n public\
\ static void main(String[] args) {\n try {\n JSch jsch = new\
\ JSch();\n Session session = jsch.getSession(\"username\", \"hostname\"\
, 22);\n session.setPassword(\"password\");\n session.setConfig(\"\
StrictHostKeyChecking\", \"no\");\n session.connect();\n \
\ System.out.println(\"Connected securely.\");\n } catch (Exception e)\
\ {\n System.err.println(\"Secure connection failed: \" + e.getMessage());\n\
\ }\n }\n}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
languages:
- java
pattern: '(org.apache.commons.net.telnet.TelnetClient $TELNETCLIENT).connect(...);
'
- id: java_crypto_rule-UnirestHTTPRequest
languages:
- java
patterns:
- pattern: 'Unirest.$METHOD("=~/[hH][tT][tT][pP]://.*/")
'
message: "This application uses the Unirest library to send\nnetwork requests to\
\ URLs starting with 'http://'. Communicating over HTTP\nis considered insecure\
\ because it does not encrypt traffic with TLS\n(Transport Layer Security), exposing\
\ data to potential interception or\nmanipulation by attackers.\n\nTo mitigate\
\ the issue, modify the request URL to begin with 'https://' \ninstead of 'http://'.\
\ Using HTTPS ensures that the data is encrypted and \nsecure during transmission.\
\ Review all instances where HTTP is used and \nupdate them to use HTTPS to prevent\
\ security risks.\n\nSecure Code Example:\n```\nimport kong.unirest.core.Unirest;\n\
\npublic void safe() {\n Unirest.get(\"https://httpbin.org\")\n .queryString(\"\
fruit\", \"apple\")\n .queryString(\"droid\", \"R2D2\")\n .asString();\n\
}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://kong.github.io/unirest-java/#requests
subcategory:
- vuln
technology:
- unirest
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
- id: java_crypto_rule-SocketRequestUnsafeProtocols
message: "This code establishes a network connection using an insecure protocol\n\
(HTTP, FTP, or Telnet). These protocols transmit data in cleartext, which\ncan\
\ be intercepted and read by malicious actors. This exposure of\nsensitive information\
\ violates security best practices and can lead to\ndata breaches.\n\nTo mitigate\
\ the vulnerability, consider using secure protocols that encrypt\nthe transmission\
\ of data. For web traffic, replace HTTP with HTTPS, which\nuses SSL/TLS to protect\
\ the data in transit. For file transfers, use SFTP\nor FTPS instead of FTP. For\
\ remote terminal access, use SSH instead of Telnet.\n\nSecure Code Example:\n\
```\npublic void safe() {\n BufferedReader in = null;\n PrintWriter out = null;\n\
\ Socket pingSocket = null;\n try{\n pingSocket = new Socket(\"ssh://example.com\"\
, 22);\n out = new PrintWriter(pingSocket.getOutputStream(), true);\n \
\ in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream()));\n\
\ out.println(\"ping\");\n System.out.println(in.readLine());\n }\
\ catch (Exception e) {\n e.printStackTrace();\n } finally {\n \
\ try {\n if (in != null) in.close();\n if (pingSocket != null)\
\ pingSocket.close();\n } catch (IOException e) {\n System.out.println(\"\
Failed to close resources: \" + e.getMessage());\n }\n }\n}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: LOW
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
languages:
- java
pattern-either:
- pattern: '$SOCKET = new java.net.Socket("=~/^ftp://.+/i", ...);
'
- pattern: '$SOCKET = new java.net.Socket("=~/^http://.+/i", ...);
'
- pattern: '$SOCKET = new java.net.Socket("=~/^telnet://.+/i", ...);
'
- patterns:
- pattern: '$SOCKET = new java.net.Socket("...", $PORT);
'
- metavariable-comparison:
comparison: $PORT in [23,21,80]
metavariable: $PORT
- id: java_crypto_rule-DisallowOldTLSVersion
languages:
- java
patterns:
- pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS");
- metavariable-pattern:
metavariable: $PATTERNS
language: generic
patterns:
- pattern-either:
- pattern-regex: ^(.*TLSv1|.*SSLv.*)$
- pattern-regex: ^(.*TLSv1,.*|.*TLSv1.1.*)
message: "This application sets the `jdk.tls.client.protocols` system property to\n\
include insecure TLS or SSL versions (SSLv3, TLSv1, TLSv1.1), which are\ndeprecated\
\ due to serious security vulnerabilities like POODLE attacks and\nsusceptibility\
\ to man-in-the-middle attacks. Continuing to use these\nprotocols can expose\
\ data to interception or manipulation. \n\nTo mitigate the issue, upgrade to\
\ TLSv1.2 or higher, which provide stronger \nencryption and improved security.\
\ Refrain from using any SSL versions as they \nare entirely deprecated.\n\nSecure\
\ Code Example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"\
jdk.tls.client.protocols\", \"TLSv1.3\");\n}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
shortDescription: Inadequate encryption strength
category: security
cwe: CWE-326
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
- id: java_crypto_rule_JwtDecodeWithoutVerify
languages:
- java
message: Detected the decoding of a JWT token without a verify step. JWT tokens
must be verified before use, otherwise the token's integrity is unknown. This
means a malicious actor could forge a JWT token with any claims. Call '.verify()'
before using the token.
metadata:
shortDescription: Improper verification of cryptographic signature
category: security
cwe: CWE-347
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
technology: jwt
confidence: MEDIUM
references: https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures
subcategory: vuln
likelihood: LOW
impact: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class: Improper Authentication
security-severity: MEDIUM
severity: WARNING
patterns:
- pattern: 'com.auth0.jwt.JWT.decode(...);
'
- pattern-not-inside: "class $CLASS {\n ...\n $RETURNTYPE $FUNC (...) {\n ...\n\
\ $VERIFIER.verify(...);\n ...\n }\n}"
- id: java_crypto_rule-UseOfRC2
languages:
- java
pattern-either:
- pattern: 'javax.crypto.Cipher.getInstance("RC2")
'
- patterns:
- pattern-inside: "class $CLS{\n ...\n String $ALG = \"RC2\";\n ...\n}\n"
- pattern: 'javax.crypto.Cipher.getInstance($ALG);
'
message: "Use of RC2, a deprecated cryptographic algorithm vulnerable to related-key\n\
attacks, was detected. Modern cryptographic standards recommend the\nadoption\
\ of algorithms that integrate message integrity to ensure the\nciphertext remains\
\ unaltered.\n\nTo mitigate the issue, use any of the below algorithms instead:\n\
1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \n\
environments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly\
\ recommended when hardware support is available, \ndespite being somewhat slower\
\ than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM\
\ to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305`\
\ in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom\
\ random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit\
\ key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n\
\ random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\"\
);\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n\
\ GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE,\
\ keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n\
\ byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"\
Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE,\
\ keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"\
Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more\
\ on Java Cryptography, refer:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n"
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- java
security-severity: MEDIUM
references:
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: HIGH
- id: java_crypto_rule-SpringFTPRequest
languages:
- java
mode: taint
pattern-sources:
- pattern: '"=~/^ftp://.+/i"
'
pattern-sinks:
- patterns:
- pattern: '(org.springframework.integration.ftp.session.DefaultFtpSessionFactory
$SF).setHost($URL);
'
- focus-metavariable: $URL
message: "This pattern detects configurations where the Spring Integration FTP plugin\
\ \nis used to set up connections to FTP servers. FTP is an insecure protocol\
\ \nthat transmits data, including potentially sensitive information, in plaintext.\
\ \nThis can expose personal identifiable information (PII) or other sensitive\
\ data \nto interception by attackers during transmission. \n\nTo mitigate the\
\ vulnerability, switch to a secure protocol such as SFTP or FTPS \nthat encrypts\
\ the connection to prevent data exposure. Ensure that any method \nused to set\
\ the host for an FTP session does not use plaintext FTP. \n\nSecure Code Example:\n\
```\npublic SessionFactory<FTPFile> safe(FtpSessionFactoryProperties properties)\
\ {\n DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();\n\
\ ftpSessionFactory.setHost(\"sftp://example.com\");\n ftpSessionFactory.setPort(properties.getPort());\n\
\ ftpSessionFactory.setUsername(properties.getUsername());\n ftpSessionFactory.setPassword(properties.getPassword());\n\
\ ftpSessionFactory.setClientMode(properties.getClientMode().getMode());\n return\
\ ftpSessionFactory;\n}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
cwe: CWE-319
category: security
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int-
subcategory:
- vuln
technology:
- spring
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
- id: java_crypto_rule-UseOfRC4
languages:
- java
pattern-either:
- pattern: 'javax.crypto.Cipher.getInstance("RC4")
'
- patterns:
- pattern-inside: "class $CLS{\n ...\n String $ALG = \"RC4\";\n ...\n}\n"
- pattern: 'javax.crypto.Cipher.getInstance($ALG);
'
message: "Use of RC4 was detected. RC4 is vulnerable to several types of attacks,\n\
including stream cipher attacks where attackers can recover plaintexts by\nanalyzing\
\ a large number of encrypted messages, and bit-flipping attacks\nthat can alter\
\ messages without knowing the encryption key.\n\nTo mitigate the issue, use any\
\ of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its\
\ simplicity and speed, suitable for \nenvironments where cryptographic acceleration\
\ is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available,\
\ \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid\
\ \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code\
\ example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt()\
\ throws Exception {\n SecureRandom random = new SecureRandom();\n byte[]\
\ secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12];\
\ // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\
\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\"\
);\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n\
\ GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE,\
\ keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n\
\ byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"\
Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE,\
\ keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"\
Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more\
\ information, refer:\nhttps://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions\n"
severity: WARNING
metadata:
shortDescription: Use of a broken or risky cryptographic algorithm
category: security
cwe: CWE-327
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
technology:
- java
security-severity: MEDIUM
references:
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
- https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: HIGH
- id: java_crypto_rule-TLSUnsafeRenegotiation
languages:
- java
patterns:
- pattern: 'java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation",
$TRUE);
'
- metavariable-pattern:
metavariable: $TRUE
pattern-either:
- pattern: 'true
'
- pattern: '"true"
'
- pattern: 'Boolean.TRUE
'
message: "This code enables unsafe renegotiation in SSL/TLS connections, which is\n\
vulnerable to man-in-the-middle attacks. In such attacks, an attacker\ncould inject\
\ chosen plaintext at the beginning of the secure\ncommunication, potentially\
\ compromising the security of data transmission. If \nexploited, this vulnerability\
\ can lead to unauthorized access to sensitive \ndata, data manipulation, and\
\ potentially full system compromise depending on \nthe data and operations protected\
\ by the TLS session.\n\nTo mitigate this vulnerability, disable unsafe renegotiation\
\ in the Java \napplication. Ensure that only secure renegotiation is allowed\
\ by setting the \nsystem property `sun.security.ssl.allowUnsafeRenegotiation`\
\ to `false`. \n\nSecure code example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"\
sun.security.ssl.allowUnsafeRenegotiation\", false);\n}\n```\n"
severity: WARNING
metadata:
likelihood: LOW
impact: MEDIUM
confidence: MEDIUM
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://www.oracle.com/java/technologies/javase/tlsreadme.html
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
- id: java_crypto_rule-HttpComponentsRequest
message: "Detected an HTTP GET request sent via Apache HTTP Components. Sending\
\ data\nover HTTP can expose sensitive information to interception or modification\n\
by attackers, as HTTP does not encrypt the data transmitted. It is critical\n\
to use HTTPS, which encrypts the communication, to protect the confidentiality\n\
and integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted\
\ between the client and \nserver is sent over HTTPS. Update all HTTP URLs to\
\ HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally,\
\ implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\
Secure Code Example:\n```\nprivate static void safe() {\n CloseableHttpClient\
\ httpclient = HttpClients.createDefault();\n CloseableHttpResponse response\
\ = httpclient.execute(new HttpPost(\"https://example.com\"));\n}\n```\n"
severity: WARNING
metadata:
shortDescription: Cleartext transmission of sensitive information
security-severity: MEDIUM
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
category: security
cwe: CWE-319
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
references:
- https://hc.apache.org/httpcomponents-client-ga/quickstart.html
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
languages:
- java
mode: taint
pattern-sources:
- pattern: '"=~/^http://.+/i"
'
pattern-sinks:
- pattern: (org.apache.http.impl.client.CloseableHttpClient $A).execute($HTTPREQ);
- id: java_crypto_rule-HTTPUrlConnectionHTTPRequest
message: "Detected an HTTP request sent via HttpURLConnection or URLConnection.\n\
This could lead to sensitive information being sent over an insecure \nchannel,\
\ as HTTP does not encrypt data. Transmitting data over HTTP \nexposes it to potential\
\ interception by attackers, risking data \nintegrity and confidentiality. Using\
\ HTTP for transmitting sensitive \ndata such as passwords, personal information,\
\ or financial details can \nlead to information disclosure.\n\nTo mitigate the\
\ issue, switch to HTTPS to ensure all data transmitted \nis securely encrypted.\
\ This helps protect against eavesdropping and \nman-in-the-middle attacks. Modify\
\ the URL in your code from HTTP to \nHTTPS and ensure the server supports HTTPS.\n\
\nSecure Code Example:\n```\nprivate static void safe() {\n try {\n \
\ URL url = new URL(\"https://example.com/api/data\"); // Changed to HTTPS\n \
\ HttpURLConnection con = (HttpURLConnection) url.openConnection();\n \
\ con.setRequestMethod(\"GET\");\n\n int status = con.getResponseCode();\n\
\ if (status == HttpURLConnection.HTTP_OK) { \n BufferedReader\
\ in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n \
\ String inputLine;\n StringBuilder response = new StringBuilder();\n\
\ while ((inputLine = in.readLine()) != null) {\n response.append(inputLine);\n\
\ }\n in.close();\n System.out.println(\"Response:\
\ \" + response.toString());\n } else {\n System.out.println(\"\
HTTP error code: \" + status);\n }\n con.disconnect();\n } catch\
\ (Exception e) {\n e.printStackTrace();\n }\n}\n```\n"
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
shortDescription: Cleartext transmission of sensitive information
category: security
cwe: CWE-319
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection()
subcategory:
- vuln
technology:
- java
vulnerability: Insecure Transport
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Mishandled Sensitive Information
languages:
- java
patterns:
- pattern: '"=~/[Hh][Tt][Tt][Pp]://.*/"
'
- pattern-either:
- pattern-inside: 'URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...);
...
$CON = (HttpURLConnection) $URL.openConnection(...);
...
$CON.$FUNC(...);
'
- pattern-inside: 'URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...);
...
$CON = $URL.openConnection(...);
...
$CON.$FUNC(...);
'
- id: java_xxe_rule-ExternalGeneralEntitiesTrue
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
category: security
technology:
- java
- xml
cwe2022-top25: 'true'
cwe2021-top25: 'true'
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "This rule identifies instances in the code where an XML parser is\nconfigured\
\ to allow external general entities. Allowing the processing \nof external general\
\ entities without proper validation or restriction \ncan lead to XXE attacks.\
\ An attacker can craft an XML document to \nreference sensitive files on the\
\ server or external systems under the \nattacker's control, leading to data disclosure,\
\ denial of service, or \nserver-side request forgery (SSRF).\n\nTo mitigate this\
\ vulnerability, the application should be configured to \ndisable the use of\
\ external general entities in XML parsing. This can be \nachieved by setting\
\ the feature \n\"http://xml.org/sax/features/external-general-entities\" to false.\n\
\nSecure Code Example:\n```\nclass GoodSAXBuilder {\n public void GoodSAXBuilder1()\
\ throws ParserConfigurationException {\n SAXBuilder saxBuilder = new SAXBuilder();\n\
\ saxBuilder.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n }\n}\n```\n"
pattern: '$PARSER.setFeature("http://xml.org/sax/features/external-general-entities",
true);
'
- id: java_xxe_rule-DocumentBuilderFactoryDisallowDoctypeDeclMissing
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
- https://xerces.apache.org/xerces2-j/features.html
category: security
security-severity: MEDIUM
technology:
- java
- xml
cwe2022-top25: 'true'
cwe2021-top25: 'true'
subcategory:
- vuln
likelihood: LOW
impact: HIGH
confidence: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "DOCTYPE declarations are enabled for this DocumentBuilderFactory. Enabling\
\ \nDOCTYPE declarations without proper restrictions can make your application\
\ \nvulnerable to XML External Entity (XXE) attacks. \nIn an XXE attack, an attacker\
\ can exploit the processing of external entity \nreferences within an XML document\
\ to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server\
\ Side Request Forgery), potentially \nleading to sensitive information disclosure\
\ or system compromise. \n\nTo mitigate this vulnerability, disable this by setting\
\ the\nfeature \"http://apache.org/xml/features/disallow-doctype-decl\" to true.\n\
Alternatively, allow DOCTYPE declarations and only prohibit external\nentities\
\ declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\"\
\ and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\
\nSecure Code Example (You can do either of the following):\n```\npublic void\
\ GoodDocumentBuilderFactory() throws ParserConfigurationException {\n DocumentBuilderFactory\
\ dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\"\
, true);\n dbf.newDocumentBuilder();\n}\n\npublic void GoodDocumentBuilderFactory2()\
\ throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n\
\ dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n dbf.newDocumentBuilder();\n}\n```\n"
mode: taint
pattern-sources:
- by-side-effect: true
patterns:
- pattern: '$FACTORY
'
- pattern-inside: '$FACTORY = DocumentBuilderFactory.newInstance();
'
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = DocumentBuilderFactory.newInstance();\n\
\ ...\n static {\n ...\n $FACTORY.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\"\
, true);\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = DocumentBuilderFactory.newInstance();\n\
\ ...\n static {\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = DocumentBuilderFactory.newInstance();\n\
\ ...\n static {\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n }\n ...\n}\n"
pattern-sinks:
- patterns:
- pattern: '$FACTORY.newDocumentBuilder();
'
pattern-sanitizers:
- by-side-effect: true
pattern-either:
- patterns:
- pattern-either:
- pattern: '$FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
true);
'
- pattern: '$FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",
false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities",
false);
'
- pattern: '$FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities",
false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",
false);
'
- focus-metavariable: $FACTORY
- patterns:
- pattern-either:
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://apache.org/xml/features/disallow-doctype-decl\",\n true);\n\
\ ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://xml.org/sax/features/external-general-entities\", false);\n \
\ ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://xml.org/sax/features/external-parameter-entities\", false);\n \
\ ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
,false);\n ...\n }\n ...\n}\n"
- pattern: $M($X)
- focus-metavariable: $X
- id: java_xxe_rule-DisallowDoctypeDeclFalse
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
- https://xerces.apache.org/xerces2-j/features.html
category: security
technology:
- java
- xml
cwe2022-top25: 'true'
cwe2021-top25: 'true'
likelihood: LOW
impact: HIGH
confidence: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting\n\
external entity declarations, this is vulnerable to XML external entity\nattacks.\
\ In an XXE attack, an attacker can exploit the processing of external \nentity\
\ references within an XML document to access internal files, conduct \ndenial-of-service\
\ attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive\
\ information disclosure or system compromise.\n\nTo mitigate this vulnerability,\
\ disable this by setting the feature\n\"http://apache.org/xml/features/disallow-doctype-decl\"\
\ to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\n\
entities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\"\
\ and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\
\nSecure Code Example: \n``` \npublic void GoodXMLInputFactory() throws ParserConfigurationException\
\ {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"\
http://apache.org/xml/features/disallow-doctype-decl\", true);\n} \n```\n"
patterns:
- pattern: '$DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
false);
'
- pattern-not-inside: "$RETURNTYPE $METHOD(...){\n ...\n $DBF.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n $DBF.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n}\n"
- pattern-not-inside: "$RETURNTYPE $METHOD(...){\n ...\n $DBF.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n $DBF.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n}\n"
- pattern-not-inside: "$RETURNTYPE $METHOD(...){\n ...\n $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n ...\n $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, \"\
\");\n ...\n}\n"
- pattern-not-inside: "$RETURNTYPE $METHOD(...){\n ...\n $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA,\
\ \"\");\n ...\n $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, \"\"\
);\n ...\n}\n"
- id: java_xxe_rule-ExternalParameterEntitiesTrue
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
category: security
technology:
- java
- xml
cwe2022-top25: 'true'
cwe2021-top25: 'true'
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "This rule identifies instances in the code where the XML parser is\nconfigured\
\ to allow external parameter entities. Enabling external\nentities in XML parsing\
\ can lead to XML External Entity (XXE) attacks,\nwhere an attacker could exploit\
\ the XML parser to read sensitive files\nfrom the server, perform denial of service\
\ (DoS) attacks, or achieve\nserver-side request forgery (SSRF). This vulnerability\
\ occurs when the\napplication processes XML input that includes external entity\
\ references\nwithin an XML document.\n\nTo mitigate this vulnerability, the application\
\ should be configured to disable \nthe use of external entities in XML parsing.\
\ This can be achieved by setting the \nfeature \"http://xml.org/sax/features/external-parameter-entities\"\
\ to false.\n\nSecure Code Example: \n``` \ntry {\n DBFactory dbFactory = DocumentBuilderFactory.newInstance();\n\
\ // Disable external entities to mitigate XXE vulnerability\n dbFactory.setFeature(\"\
http://xml.org/sax/features/external-parameter-entities\", false);\n dbFactory.setFeature(\"\
http://apache.org/xml/features/disallow-doctype-decl\", true);\n // Additional\
\ configuration for secure parsing\n dbFactory.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n dbFactory.setXIncludeAware(false);\n dbFactory.setExpandEntityReferences(false);\n\
\n // Use the configured factory to create a document builder\n DocumentBuilder\
\ dBuilder = dbFactory.newDocumentBuilder();\n // Parse an XML file using the\
\ secure document builder\n Document doc = dBuilder.parse(new InputSource(new\
\ StringReader(xmlData)));\n // Process the document as needed\n} catch (ParserConfigurationException\
\ | SAXException | IOException e) {\n // Handle exceptions appropriately\n\
} \n``` \n"
pattern: '$PARSER.setFeature("http://xml.org/sax/features/external-parameter-entities",
true);
'
- id: java_xxe_rule-XMLInputFactoryExternalEntitiesEnabled
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
category: security
cwe2022-top25: 'true'
cwe2021-top25: 'true'
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "XML external entities are enabled for this XMLInputFactory. Enabling external\
\ \nentities can make the application vulnerable to XML external entity attacks.\
\ \nIn an XXE attack, an attacker can exploit the processing of external entity\
\ \nreferences within an XML document to access internal files, conduct \ndenial-of-service\
\ attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive\
\ information disclosure or system compromise.\n\nTo mitigate this vulnerability,\
\ disable external entities by\nsetting \"javax.xml.stream.isSupportingExternalEntities\"\
\ to false.\n\nSecure Code Example:\n```\npublic GoodXMLInputFactory() {\n final\
\ XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();\n xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD,\
\ false);\n xmlInputFactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\"\
, false);\n}\n```\nFor more details, refer to https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md#xmlinputfactory-a-stax-parser\n"
pattern: '$XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities",
true);
'
- id: java_xxe_rule-TransformerfactoryDTDNotDisabled
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
- https://xerces.apache.org/xerces2-j/features.html
category: security
technology:
- java
- xml
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
message: "This rule identifies configurations of the TransformerFactory class where\n\
DOCTYPE declarations are enabled. Enabling DOCTYPE declarations without\nproper\
\ restrictions can make your application vulnerable to XML External\nEntity (XXE)\
\ attacks. In an XXE attack, an attacker can exploit the\nprocessing of external\
\ entity references within an XML document to access\ninternal files, conduct\
\ denial-of-service attacks, or SSRF (Server Side\nRequest Forgery), potentially\
\ leading to sensitive information disclosure\nor system compromise.\n\nTo mitigate\
\ XXE vulnerabilities related to the TransformerFactory instance in \nJava, it\
\ is crucial to disable external DTD (Document Type Definition) and \nexternal\
\ stylesheet processing. This can be accomplished by setting the \nACCESS_EXTERNAL_DTD\
\ and ACCESS_EXTERNAL_STYLESHEET factory attributes to an \nempty string (\"\"\
). This approach prevents the parser from fetching and processing \nexternal references\
\ specified in the XML document.\n\nSecure Code Example:\n```\npublic static void\
\ configureTransformerFactory() throws TransformerConfigurationException {\n \
\ TransformerFactory factory = TransformerFactory.newInstance();\n // Disable\
\ access to external DTDs and stylesheets to prevent XXE\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, \"\"\
);\n}\n```\n"
mode: taint
pattern-sources:
- by-side-effect: true
patterns:
- pattern-either:
- pattern: '$FACTORY = javax.xml.transform.TransformerFactory.newInstance();
'
- patterns:
- pattern: $FACTORY
- pattern-inside: "class $C {\n ...\n $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance();\n\
\ ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,\
\ \"\");\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,\
\ \"\");\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setAttribute(\"=~/.*accessExternalDTD.*/\"\
, \"\");\n ...\n $FACTORY.setAttribute(\"=~/.*accessExternalStylesheet.*/\"\
, \"\");\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setAttribute(\"=~/.*accessExternalStylesheet.*/\"\
, \"\");\n ...\n $FACTORY.setAttribute(\"=~/.*accessExternalDTD.*/\"\
, \"\");\n ...\n }\n ...\n}\n"
pattern-sinks:
- patterns:
- pattern: $FACTORY.newTransformer(...);
pattern-sanitizers:
- by-side-effect: true
pattern-either:
- patterns:
- pattern-either:
- pattern: '$FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,
""); ...
$FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
'
- pattern: '$FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
...
$FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
'
- pattern: '$FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", "");
...
$FACTORY.setAttribute("=~/.*accessExternalDTD.*/", "");
'
- pattern: '$FACTORY.setAttribute("=~/.*accessExternalDTD.*/", "");
...
$FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", "");
'
- focus-metavariable: $FACTORY
- patterns:
- pattern-either:
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,\
\ \"\");\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,\
\ \"\");\n ...\n $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,\
\ \"\");\n ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setAttribute(\"\
=~/.*accessExternalStylesheet.*/\", \"\");\n ...\n $FACTORY.setAttribute(\"\
=~/.*accessExternalDTD.*/\", \"\");\n ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setAttribute(\"\
=~/.*accessExternalDTD.*/\", \"\");\n ...\n $FACTORY.setAttribute(\"\
=~/.*accessExternalStylesheet.*/\", \"\");\n ...\n }\n ...\n}\n"
- pattern: $M($X)
- focus-metavariable: $X
- id: java_xxe_rule-XMLStreamRdr
languages:
- java
message: "External XML entities are a feature of XML parsers that allow \ndocuments\
\ to contain references to other documents or data. This \nfeature can be abused\
\ to read files, communicate with external\nhosts, exfiltrate data, or cause a\
\ Denial of Service (DoS).\nIn most XML parsers, the recommendation to protect\
\ against XXE is \nto disable the doctype feature.\nUnfortunately use of the `XMLInputFactory`\
\ requires that the doctypes \nfeature be enabled. Instead the application can\
\ set the `ACCESS_EXTERNAL_DTD` \nto an empty string and disable `javax.xml.stream.isSupportingExternalEntities`.\n\
\nSecure Code Example:\n```\n// Create an XMLInputFactory\nXMLInputFactory factory\
\ = XMLInputFactory.newFactory();\n// Set the ACCESS_EXTERNAL_DTD property to\
\ an empty string so it won't access\n// entities using protocols\n// (ref:\n\
https://docs.oracle.com/javase/8/docs/api/javax/xml/XMLConstants.html#ACCESS_EXTERNAL_DTD)\n\
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n// Additionally,\
\ disable support for resolving external entities\nfactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\"\
, false);\n// Continue to work with the factory/stream parser\n```\n\nFor more\
\ information on XML security see OWASP's guide:\nhttps://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java\n"
patterns:
- pattern-not-inside: '(javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
"");
...
'
- pattern-not-inside:
patterns:
- pattern-either:
- pattern: '(javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.SUPPORT_DTD,
$FALSE);
...
'
- pattern: '(javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
$FALSE);
...
'
- pattern: '(javax.xml.stream.XMLInputFactory $FAC).setProperty("javax.xml.stream.isSupportingExternalEntities",
$FALSE);
...
'
- metavariable-pattern:
metavariable: $FALSE
pattern-either:
- pattern: 'false
'
- pattern: 'Boolean.FALSE
'
- pattern: '(javax.xml.stream.XMLInputFactory $FAC).createXMLStreamReader(...)
'
metadata:
shortDescription: Improper restriction of XML external entity reference ('XXE')
category: security
cwe: CWE-611
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
severity: WARNING
- id: java_xxe_rule-SAXParserFactoryDisallowDoctypeDeclMissing
severity: WARNING
languages:
- java
metadata:
cwe: CWE-611
shortDescription: Improper restriction of XML external entity reference
owasp:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
references:
- https://semgrep.dev/blog/2022/xml-security-in-java
- https://semgrep.dev/docs/cheat-sheets/java-xxe/
- https://blog.sonarsource.com/secure-xml-processor
- https://xerces.apache.org/xerces2-j/features.html
category: security
technology:
- java
- xml
cwe2022-top25: 'true'
cwe2021-top25: 'true'
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
message: "DOCTYPE declarations are enabled for this SAXParserFactory. Enabling DOCTYPE\
\ \ndeclarations without proper restrictions can make your application vulnerable\
\ to \nXML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can\
\ exploit the processing of external entity \nreferences within an XML document\
\ to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server\
\ Side Request Forgery), potentially \nleading to sensitive information disclosure\
\ or system compromise.\n\nTo mitigate this vulnerability, disable DOCTYPE declarations\
\ by setting the\nfeature `http://apache.org/xml/features/disallow-doctype-decl`\
\ to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\n\
entities declarations. This can be done by setting the features\n`http://xml.org/sax/features/external-general-entities`\
\ and\n`http://xml.org/sax/features/external-parameter-entities` to false. \n\
NOTE: The previous links are not meant to be clicked. They are the literal\nconfig\
\ key values that are supposed to be used to disable these features.\n\nSecure\
\ Code Example (You can do either of the following):\n```\npublic void GoodSAXParserFactory()\
\ throws ParserConfigurationException {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n\
\ spf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n\
\ spf.newSAXParser();\n}\n\npublic void GoodSAXParserFactory2() throws ParserConfigurationException\
\ {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n spf.setFeature(\"\
http://xml.org/sax/features/external-parameter-entities\", false);\n spf.setFeature(\"\
http://xml.org/sax/features/external-general-entities\", false);\n spf.newSAXParser();\n\
} \n```\nFor more information, see\nhttps://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.\n"
mode: taint
pattern-sources:
- by-side-effect: true
patterns:
- pattern-either:
- pattern: '$FACTORY = SAXParserFactory.newInstance();
'
- patterns:
- pattern: $FACTORY
- pattern-inside: "class $C {\n ...\n $V $FACTORY = SAXParserFactory.newInstance();\n\
\ ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = SAXParserFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\"\
, true);\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = SAXParserFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n }\n ...\n}\n"
- pattern-not-inside: "class $C {\n ...\n $V $FACTORY = SAXParserFactory.newInstance();\n\
\ static {\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
, false);\n ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n }\n ...\n}\n"
pattern-sinks:
- patterns:
- pattern: $FACTORY.newSAXParser();
pattern-sanitizers:
- by-side-effect: true
pattern-either:
- patterns:
- pattern-either:
- pattern: '$FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
true);
'
- pattern: '$FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",
false);
...
$FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities",
false);
'
- pattern: '$FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities",
false);
...
$FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",
false);
'
- focus-metavariable: $FACTORY
- patterns:
- pattern-either:
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://apache.org/xml/features/disallow-doctype-decl\",\n true);\n\
\ ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://xml.org/sax/features/external-general-entities\", false);\n \
\ ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-parameter-entities\"\
, false);\n ...\n }\n ...\n}\n"
- pattern-inside: "class $C {\n ...\n $T $M(...) {\n ...\n $FACTORY.setFeature(\"\
http://xml.org/sax/features/external-parameter-entities\", false);\n \
\ ...\n $FACTORY.setFeature(\"http://xml.org/sax/features/external-general-entities\"\
,false);\n ...\n }\n ...\n}\n"
- pattern: $M($X)
- focus-metavariable: $X
- id: java_file_rule_rule-FilePathTraversalHttpServlet
languages:
- java
severity: ERROR
metadata:
security-severity: CRITICAL
shortDescription: Improper Limitation of a Pathname to a Restricted Directory
('Path Traversal')
cwe: CWE-22
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN
references:
- https://www.owasp.org/index.php/Path_Traversal
category: security
technology:
- java
cwe2022-top25: true
cwe2021-top25: true
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Path Traversal
message: "Detected a potential path traversal. A malicious actor could control\n\
the location of this file, to include going backwards in the directory\nwith '../'.\
\ \n\nTo address this, ensure that user-controlled variables in file\npaths are\
\ sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...)\
\ to only retrieve the file\nname from the path.\n\nExample code using FilenameUtils.getName(...)\n\
\n```\npublic void ok(HttpServletRequest request, HttpServletResponse response)\n\
\ throws ServletException, IOException {\n String image = request.getParameter(\"\
image\");\n File file = new File(\"static/images/\", FilenameUtils.getName(image));\n\
\n if (!file.exists()) {\n log.info(image + \" could not be created.\"\
);\n response.sendError();\n }\n\n response.sendRedirect(\"/index.html\"\
);\n}\n```\n"
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: '(HttpServletRequest $REQ)
'
- patterns:
- pattern-inside: "(javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest\
\ $REQ).getCookies(...); ...\nfor (javax.servlet.http.Cookie $COOKIE:\
\ $COOKIES) {\n ...\n}\n"
- pattern: '$COOKIE.getValue(...)
'
- patterns:
- pattern-inside: '$TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...);
...
'
- pattern: '$PARAM = $VALS[$INDEX];
'
pattern-sanitizers:
- pattern: org.apache.commons.io.FilenameUtils.getName(...)
pattern-sinks:
- patterns:
- pattern-either:
- pattern: '(java.io.File $FILE) = ...
'
- pattern: '(java.io.FileOutputStream $FOS) = ...
'
- pattern: 'new java.io.FileInputStream(...)
'
- id: java_inject_rule-EnvInjection
message: "Detected input from a HTTPServletRequest going into the environment\n\
variables of an 'exec' command. The user input is passed directly to\nthe Runtime.exec()\
\ function to set an environment variable. This allows \nmalicious input from\
\ the user to modify the command that will be executed.\nTo remediate this, do\
\ not pass user input directly to Runtime.exec().\nValidate any user input before\
\ using it to set environment variables \nor command arguments. Consider using\
\ an allow list of allowed values\nrather than a deny list. If dynamic commands\
\ must be constructed, use\na map to look up valid values based on user input\
\ instead of using \nthe input directly.\nExample of safely executing an OS command:\n\
```\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\n\
\ throws ServletException, IOException {\n response.setContentType(\"text/html;charset=UTF-8\"\
);\n\n String param = \"\";\n if (request.getHeader(\"UserDefined\") != null)\
\ {\n param = request.getHeader(\"UserDefined\");\n }\n\n param = java.net.URLDecoder.decode(param,\
\ \"UTF-8\");\n String cmd = \"/bin/cmd\";\n\n String[] allowList = {\"FOO=true\"\
,\"FOO=false\",\"BAR=true\", \"BAR=false\"}\n if(Arrays.asList(allowList).contains(param)){\n\
\ String[] argsEnv = {param};\n }\n \n Runtime r = Runtime.getRuntime();\n\
\n try {\n Process p = r.exec(cmd, argsEnv);\n printOSCommandResults(p,\
\ response); \n } catch (IOException e) {\n System.out.println(\"\
Problem executing command\");\n response.getWriter()\n .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage()));\n\
\ return;\n }\n```\n"
languages:
- java
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: '(HttpServletRequest $REQ)
'
- patterns:
- pattern-inside: '$FUNC(..., $VAR, ...) {
...
}
'
- pattern: $VAR
pattern-sinks:
- pattern-either:
- patterns:
- pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...);
- focus-metavariable: $ENV_ARGS
- patterns:
- pattern: (ProcessBuilder $PB).environment().put($...ARGS);
- focus-metavariable: $...ARGS
- patterns:
- pattern: '$ENV = (ProcessBuilder $PB).environment();
...
$ENV.put($...ARGS);
'
- focus-metavariable: $...ARGS
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern: 'if($VALIDATION){
...
}
'
- patterns:
- pattern-inside: '$A = $VALIDATION;
...
'
- pattern: 'if($A){
...
}
'
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: '$AL.contains(...)
'
metadata:
shortDescription: Improper neutralization of special elements used in an OS command
('OS Command Injection')
category: security
technology:
- java
cwe: CWE-78
owasp:
- A1:2017-Injection
- A03:2021-Injection
references:
- https://owasp.org/Top10/A03_2021-Injection
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Other
security-severity: HIGH
- id: java_inject_rule-SqlInjection
languages:
- java
options:
taint_assume_safe_booleans: true
taint_assume_safe_numbers: true
message: "SQL Injection is a critical vulnerability that can lead to data or system\
\ compromise. By\ndynamically generating SQL query strings, user input may be\
\ able to influence the logic of\nthe SQL statement. This could lead to an adversary\
\ accessing information they should\nnot have access to, or in some circumstances,\
\ being able to execute OS functionality or code.\n\nReplace all dynamically generated\
\ SQL queries with parameterized queries. In situations where\ndynamic queries\
\ must be created, never use direct user input, but instead use a map or\ndictionary\
\ of valid values and resolve them using a user-supplied key.\n\nFor example,\
\ some database drivers do not allow parameterized queries for `>` or `<` comparison\n\
operators. In these cases, do not use a user supplied `>` or `<` value, but rather\
\ have the\nuser\nsupply a `gt` or `lt` value. The alphabetical values are then\
\ used to look up the `>` and `<`\nvalues to be used in the construction of the\
\ dynamic query. The same goes for other queries\nwhere\ncolumn or table names\
\ are required but cannot be parameterized.\n\nExample using `PreparedStatement`\
\ queries:\n```\n// Some userInput\nString userInput = \"someUserInput\";\n//\
\ Your connection string\nString url = \"...\";\n// Get a connection from the\
\ DB via the DriverManager\nConnection conn = DriverManager.getConnection(url);\n\
// Create a prepared statement\nPreparedStatement st = conn.prepareStatement(\"\
SELECT name FROM table where name=?\");\n// Set each parameters value by the index\
\ (starting from 1)\nst.setString(1, userInput);\n// Execute query and get the\
\ result set\nResultSet rs = st.executeQuery();\n// Iterate over results\nwhile\
\ (rs.next()) {\n // Get result for this row at the provided column number\
\ (starting from 1)\n String result = rs.getString(1);\n // ...\n}\n// Close\
\ the ResultSet\nrs.close();\n// Close the PreparedStatement\nst.close();\n```\n\
\nExample on using CriteriaBuilder to build queries\n```\npublic List<YourEntity>\
\ findBySomeCriteria(EntityManager entityManager, String criteriaValue) {\n \
\ CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();\n \
\ CriteriaQuery<YourEntity> query = criteriaBuilder.createQuery(YourEntity.class);\n\
\ Root<YourEntity> root = query.from(YourEntity.class);\n\n query.select(root).where(criteriaBuilder.equal(root.get(\"\
someProperty\"), criteriaValue));\n\n return entityManager.createQuery(query).getResultList();\n\
}\n```\n\nFor more information on SQL Injection see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n"
mode: taint
pattern-sources:
- pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...)
- pattern: (java.util.Scanner $S).$METHOD(...)
- pattern: (java.util.stream.Stream).$METHOD(...)
- pattern: (java.util.StringJoiner $SJ).toString(...)
- pattern: (java.sql.ResultSet.getString $R).$METHOD(...)
- pattern: (java.lang.System $S).getProperty(...)
- pattern: (java.lang.System $S).getenv(...)
- pattern: (java.lang.StringBuilder $SB).toString(...)
- pattern: (java.io.FileInputStream $F).read(...)
- pattern: (java.io.FileReader $F).read(...)
- pattern: (java.net.Socket $S).getInputStream(...)
- pattern: (java.net.Socket $S).getOutputStream(...)
- pattern: (java.net.DatagramSocket $S).receive(...)
- pattern: (java.net.DatagramSocket $S).getInputStream(...)
- pattern: java.nio.file.Files.readAllBytes(...)
- pattern: java.nio.file.Files.readAllLines(...)
- pattern: java.nio.file.Files.lines(...)
- pattern: java.nio.file.Files.newBufferedReader(...)
- pattern: org.apache.commons.io.IOUtils.toString(...)
- pattern: org.apache.commons.io.IOUtils.readLines(...)
- pattern: org.apache.commons.io.IOUtils.toByteArray(...)
- pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...)
- pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...)
- pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...)
- pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...)
- patterns:
- pattern-inside: $FUNC(..., String $X, ...) { ... }
- focus-metavariable: $X
pattern-propagators:
- pattern: $LIST.add($X)
from: $X
to: $LIST
- pattern: $MAP.put(..., $X)
from: $X
to: $MAP
- pattern: $STR.concat($X)
from: $X
to: $STR
- pattern: $STR = String.format(..., $X, ...)
from: $X
to: $STR
- pattern: $STR = String.join(..., $X, ...)
from: $X
to: $STR
- pattern: $SB.append($X)
from: $X
to: $SB
pattern-sinks:
- patterns:
- pattern-either:
- pattern: (javax.jdo.PersistenceManager $PM).newQuery($ARG)
- pattern: (javax.jdo.PersistenceManager $PM).newQuery(..., $ARG)
- pattern: (javax.jdo.Query $Q).setFilter($ARG)
- pattern: (javax.jdo.Query $Q).setGrouping($ARG)
- pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...)
- pattern: (org.hibernate.Session $S).createQuery((String $ARG), ...)
- pattern: (org.hibernate.Session $S).createSQLQuery($ARG, ...)
- pattern: (org.hibernate.Session $S).connection().prepareStatement($ARG)
- pattern: (java.sql.Statement $S).executeQuery($ARG, ...)
- pattern: (java.sql.Statement $S).execute($ARG, ...)
- pattern: (java.sql.Statement $S).executeUpdate($ARG, ...)
- pattern: (java.sql.Statement $S).executeLargeUpdate($ARG, ...)
- pattern: (java.sql.Statement $S).addBatch($ARG, ...)
- pattern: (java.sql.PreparedStatement $S).executeQuery($ARG, ...)
- pattern: (java.sql.PreparedStatement $S).execute($ARG, ...)
- pattern: (java.sql.PreparedStatement $S).executeUpdate($ARG, ...)
- pattern: (java.sql.PreparedStatement $S).executeLargeUpdate($ARG, ...)
- pattern: (java.sql.PreparedStatement $S).addBatch($ARG, ...)
- pattern: (java.sql.Connection $S).prepareCall($ARG, ...)
- pattern: (java.sql.Connection $S).prepareStatement($ARG, ...)
- pattern: (java.sql.Connection $S).nativeSQL($ARG, ...)
- pattern: new org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG,
...)
- pattern: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).batchUpdate($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).execute($ARG, ...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).query($ARG, ...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForList($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForMap($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForRowSet($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForInt($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForLong($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcOperations $O).update($ARG, ...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).batchUpdate($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).execute($ARG, ...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).query($ARG, ...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForList($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForMap($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForObject($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForRowSet($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForInt($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForLong($ARG,
...)
- pattern: (org.springframework.jdbc.core.JdbcTemplate $O).update($ARG, ...)
- pattern: (io.vertx.sqlclient.SqlClient $O).query($ARG, ...)
- pattern: (io.vertx.sqlclient.SqlClient $O).preparedQuery($ARG, ...)
- pattern: (io.vertx.sqlclient.SqlConnection $O).prepare($ARG, ...)
- pattern: (org.apache.turbine.om.peer.BasePeer $O).executeQuery($ARG, ...)
- pattern: org.apache.torque.util.BasePeer.executeQuery($ARG, ...)
- pattern: org.apache.torque.util.BasePeer.executeStatement($ARG, ...)
- pattern: (javax.persistence.EntityManager $O).createQuery($ARG, ...)
- pattern: (javax.persistence.EntityManager $O).createNativeQuery($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).createQuery($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).createScript($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).createUpdate($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).execute($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).prepareBatch($ARG, ...)
- pattern: (org.jdbi.v3.core.Handle $H).select($ARG, ...)
- pattern: new org.jdbi.v3.core.statement.Script($H, $ARG)
- pattern: new org.jdbi.v3.core.statement.Update($H, $ARG)
- pattern: new org.jdbi.v3.core.statement.PreparedBatch($H, $ARG)
- focus-metavariable: $ARG
- patterns:
- pattern: (java.sql.Connection $S).createStatement(...).$SQLFUNC($ARG, ...)
- pattern-not: (java.sql.Connection $S).createStatement(...).$SQLFUNC("...")
- metavariable-regex:
metavariable: $SQLFUNC
regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare
pattern-sanitizers:
- pattern: (CriteriaBuilder $CB).$ANY(...)
metadata:
shortDescription: Improper neutralization of special elements used in an SQL command
('SQL Injection')
category: security
cwe: CWE-89
technology:
- java
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: High
severity: ERROR
- id: java_inject_rule-MongodbNoSQLi
languages:
- java
patterns:
- pattern-either:
- pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT);
- pattern: '(HashMap<String, String> $MAP).put("$where", $INPUT);
...
(com.mongodb.BasicDBObject $QUERY).putAll($MAP);
'
- pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT);
- pattern: new com.mongodb.BasicDBObject("$where", $INPUT);
- pattern: '(HashMap<String, String> $MAP).put("$where", $INPUT);
...
new com.mongodb.BasicDBObject($MAP);
'
- pattern: '(HashMap<String, String> $MAP).put("$where", $INPUT);
...
String json = new JSONObject($MAP).toString();
...
(com.mongodb.BasicDBObject $QUERY).parse((String $JSON));
'
- pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT);
- pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT);
- pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT);
- pattern: '(HashMap<String, String> $MAP).put("$where", $INPUT);
...
com.mongodb.BasicDBObjectBuilder.start($MAP);
'
- metavariable-pattern:
metavariable: $INPUT
patterns:
- pattern: '...
'
- pattern-not: '"..."
'
message: 'Detected non-constant data passed into a NoSQL query using the ''where''
evaluation operator. If this data can be controlled by an external user,
this is a NoSQL injection. Ensure data passed to the NoSQL query is not
user controllable, or properly sanitize the data. Ideally, avoid using the
''where'' operator at all and instead use the helper methods provided by
com.mongodb.client.model.Filters with comparative operators such as eq,
ne, lt, gt, etc.
Secure Code Example:
```
MongoDatabase database = mongoClient.getDatabase("mydb");
MongoCollection<Document> collection = database.getCollection("users");
// Secure usage with Filters.eq:
String username = request.getParameter("username");
collection.find(Filters.eq("username", username));
```
'
severity: ERROR
metadata:
category: security
technology:
- nosql
- mongodb
owasp:
- A1:2017-Injection
- A03:2021-Injection
cwe: CWE-943
shortDescription: Improper neutralization of special elements in data query logic
security-severity: CRITICAL
references:
- https://owasp.org/Top10/A03_2021-Injection
- https://www.mongodb.com/docs/manual/tutorial/query-documents/
- https://www.mongodb.com/docs/manual/reference/operator/query/where/
subcategory:
- audit
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Improper Validation
- id: java_inject_rule-DangerousGroovyShell
languages:
- java
patterns:
- pattern-either:
- pattern: '(groovy.lang.GroovyShell $SHELL).parse(...)
'
- pattern: '(groovy.lang.GroovyShell $SHELL).evaluate(...)
'
- pattern: '(groovy.lang.GroovyClassLoader $SHELL).parseClass(...)
'
- pattern-not: '$SHELL.parse("...",...)
'
- pattern-not: '$SHELL.evaluate("...",...)
'
- pattern-not: '$SHELL.parseClass("...",...)
'
- pattern-not-inside: "if($ALLOWLIST.contains($INPUT)){\n ...\n}\n"
message: "This application implements unsafe invocations of methods within the\n\
`groovy.lang.GroovyShell` or `groovy.lang.GroovyClassLoader` classes,\nwhich are\
\ used to evaluate or compile Groovy code dynamically. When\nuser-controlled input\
\ is directly passed to `parse`, `evaluate`, or\n`parseClass` methods, it can\
\ lead to Remote Code Execution (RCE), where an\nattacker can execute arbitrary\
\ code on the server. This could potentially\nallow an attacker to gain unauthorized\
\ access to system resources, modify\ninternal application states, or execute\
\ commands on the server depending\non the level of permissions assigned to the\
\ application process.\n\nTo mitigate this vulnerability, always validate and\
\ sanitize all user inputs \nbefore using them in dynamic code evaluations. Consider\
\ using safer alternatives \nto executing dynamic code if possible. If dynamic\
\ code execution is absolutely \nnecessary, use strict allowlists of safe inputs\
\ and context-specific validation.\n\nSecure Code Example:\n\n```\nimport groovy.lang.GroovyShell;\n\
\nclass SafeDynamicEvaluation {\n private static final Set<String> ALLOWED_EXPRESSIONS\
\ = new HashSet<>(Arrays.asList(\n \"println 'Hello World!'\",\n \"\
println 'Goodbye World!'\"));\n\n public static void test4(String[] args, ClassLoader\
\ loader) throws Exception {\n GroovyShell shell = new GroovyShell();\n \
\ String userInput = args[0];\n\n // Validate the user input against the allowlist\n\
\ if (ALLOWED_EXPRESSIONS.contains(userInput)) {\n shell.evaluate(userInput);\n\
\ // shell.parse(userInput);\n } else {\n throw new IllegalArgumentException(\"\
Invalid or unauthorized command.\");\n }\n }\n}\n```\n"
metadata:
shortDescription: Improper control of generation of code ('Code Injection')
category: security
cwe: CWE-94
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL
technology:
- groovy
references:
- https://owasp.org/Top10/A03_2021-Injection
cwe2022-top25: 'true'
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
severity: ERROR
- id: java_inject_rule-SeamLogInjection
languages:
- java
patterns:
- pattern: '$LOG.$INFO($X + $Y,...)
'
- pattern-either:
- pattern-inside: 'import org.jboss.seam.log.Log;
...
'
- pattern-inside: 'org.jboss.seam.log.Log $LOG = ...;
...
'
- metavariable-regex:
metavariable: $INFO
regex: (debug|error|fatal|info|trace|warn)
message: "The Seam logging API supports an expression language that allows developers\
\ to \nintroduce bean properties to log messages. The expression language can\
\ also be \nthe source to unwanted code execution. Expressions could be executed\
\ by dynamically\ninserting user-controlled input into the various logging calls.\
\ \n\nUse the [Seam logging API format specifier](https://docs.jboss.org/seam/2.1.2/reference/en-US/html/concepts.html#d0e4244)\
\ to ensure values are logged and expressions\nare not executed dynamically prior\
\ to output.\n\nExample logging call that safely logs the unfiltered values.\n\
```\nlog.info(\"This is a user controlled input = #0\", input);\n```\n"
severity: ERROR
metadata:
category: security
shortDescription: Improper neutralization of directives in dynamically evaluated
code ('Eval Injection')
cwe: CWE-95
owasp:
- A1:2017-Injection
- A03:2021-Injection
references:
- https://owasp.org/Top10/A03_2021-Injection
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
security-severity: CRITICAL
- id: rules_lgpl_java_webview_rule-webview-set-allow-file-access
pattern: $WB.setAllowFileAccess(true);
message: "WebView File System Access is enabled. An attacker able to inject \nscript\
\ into a WebView, could exploit the opportunity to unauthorized \naccess to sensitive\
\ user data or system files.\n\nTo fix this security issue, you should disable\
\ file access in the \nWebView or restrict it to specific directories. \nAn example:\n\
```\n// Create a WebView instance\nWebView webView = new WebView(context);\n//\
\ Disable file access in the WebView\nwebView.getSettings().setAllowFileAccess(false);\n\
```\n"
languages:
- java
severity: WARNING
metadata:
category: security
cwe: CWE-73
shortDescription: External control of file name or path
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
- id: rules_lgpl_java_webview_rule-webview-external-storage
patterns:
- pattern-either:
- pattern: '$X = <... $E.getExternalStorageDirectory() ...>;
...
$WV.loadUrl(<... $X ...>);
'
- pattern: '$WV.loadUrl(<... $E.getExternalStorageDirectory().$F() ...>);
'
- pattern: '$X = <... Environment.getExternalStorageDirectory().$F() ...>;
...
$WV.loadUrl(<... $X ...>);
'
- pattern: '$X = <... $E.getExternalFilesDir(...) ...>;
...
$WV.loadUrl(<... $X ...>);
'
message: "WebView load files from external storage. Files in external storage can\
\ be\nmodified by any application.\n\nLoading files from external storage in a\
\ WebView can introduce security risks, \nas it allows web content to access potentially\
\ sensitive data stored on the \ndevice's external storage. This can lead to unauthorized\
\ access to user data, \nincluding personal files, credentials, or other sensitive\
\ information, by \nmalicious web content.\n\nTo fix this security issue, you\
\ should avoid loading files directly from external \nstorage in a WebView. Instead,\
\ you should use a Content Provider or a secure file \nstorage mechanism to access\
\ files and provide them to the WebView as content.\n\nHere's a general approach\
\ to fix this problem:\n(1) Use a Content Provider: If you need to load files\
\ from external storage in a WebView, \nconsider using a Content Provider to securely\
\ access the files. Content Providers \nprovide controlled access to files stored\
\ on external storage and allow you to define \npermissions for accessing them.\n\
(2) Secure File Storage: Store files containing sensitive data in a secure location,\
\ such \nas internal storage or encrypted storage, and provide access to them\
\ through a secure \nAPI. Avoid exposing sensitive files directly to the WebView.\n\
(3) Restrict WebView Access: Configure the WebView to restrict access to external\
\ resources \nand content. Use methods like setAllowFileAccess() to control file\
\ access and \nsetAllowContentAccess() to control access to content from other\
\ origins.\nHere's an example of how you can use a Content Provider to provide\
\ secure access to \nfiles in a WebView:\n```\n// Define the URI of the content\
\ provider for accessing files\nUri contentProviderUri = Uri.parse(\"content://com.example.myapp.provider/files\"\
);\n// Load the content from the Content Provider into the WebView\nwebView.loadUrl(contentProviderUri.toString());\n\
```\nIn the above code, we define the URI of a Content Provider that provides\
\ access to files \nstored in the app's external storage. The content is loaded\
\ from the Content Provider into \nthe WebView using loadUrl(), which ensures\
\ that access to files is controlled and secure, \npreventing unauthorized access\
\ to sensitive data.\n"
languages:
- java
severity: ERROR
metadata:
category: security
cwe: CWE-749
shortDescription: Exposed dangerous method or function
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: CRITICAL
- id: rules_lgpl_java_webview_rule-webview-debugging
patterns:
- pattern-either:
- pattern: '$WB.setWebContentsDebuggingEnabled(true);
'
- pattern: '$X = true;
...
$WB.setWebContentsDebuggingEnabled($X);
'
message: "Remote WebView debugging is enabled. This allows an attacker with\ndebugging\
\ access to interact with the webview and steal or corrupt data.\nTo fix these\
\ security issues, it is recommended to disable remote \ndebugging and restrict\
\ file access in the WebView. \nHere's how you can do it:\n```\nWebView webView\
\ = new WebView(context);\n\n// Disable remote debugging\nif (Build.VERSION.SDK_INT\
\ >= Build.VERSION_CODES.KITKAT) {\n WebView.setWebContentsDebuggingEnabled(false);\n\
}\n\n// Restrict file access from file URLs\nwebView.getSettings().setAllowFileAccessFromFileURLs(false);\n\
\n// Load a web page\nwebView.loadUrl(\"https://example.com\");\n```\n"
languages:
- java
severity: WARNING
metadata:
category: security
cwe: CWE-489
shortDescription: Active debug code
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: MEDIUM
- id: rules_lgpl_java_webview_rule-ignore-ssl-certificate-errors
pattern: "$RET onReceivedSslError(WebView $W, SslErrorHandler $H, SslError $E) {\n\
\ ...\n $H.proceed();\n}\n"
message: "Insecure WebView Implementation. leading to a security problem known as\
\ SSL certificate \nvalidation bypass. This occurs when the app fails to properly\
\ validate SSL certificates, \nallowing potentially malicious or spoofed certificates\
\ to be accepted, leading to a \nMan-in-the-Middle (MitM) attack where an attacker\
\ intercepts and manipulates communication \nbetween the app and the server. \n\
\nTo fix this security issue, you should properly handle SSL errors and only proceed\
\ with \nthe connection if the SSL certificate is valid and trusted. Here's an\
\ example code in Java:\n``` \npublic class MyWebViewClient extends WebViewClient\
\ { \n @Override\n public void onReceivedSslError(WebView view, SslErrorHandler\
\ handler, SslError error) {\n // Check the SSL error type\n switch (error.getPrimaryError())\
\ {\n case SslError.SSL_UNTRUSTED:\n // Certificate is untrusted\n\
\ // Handle the error appropriately, such as showing an error message\n\
\ break;\n case SslError.SSL_EXPIRED:\n // Certificate has\
\ expired\n // Handle the error appropriately\n break;\n case\
\ SslError.SSL_IDMISMATCH:\n // Certificate hostname mismatch\n \
\ // Handle the error appropriately\n break;\n case SslError.SSL_NOTYETVALID:\n\
\ // Certificate is not yet valid\n // Handle the error appropriately\n\
\ break;\n }\n // Cancel the connection\n // This prevents the\
\ WebView from loading the content\n handler.cancel();\n }\n}\n```\n"
languages:
- java
severity: WARNING
metadata:
category: security
cwe: CWE-295
shortDescription: Improper certificate validation"
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
- id: java_csrf_rule-SpringCSRFDisabled
languages:
- java
pattern-either:
- pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity
$H). ... .csrf(...). ... .requireCsrfProtectionMatcher(...)
- pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity
$H). ... .csrf(...). ... .disable(...)
- pattern: (org.springframework.security.config.annotation.web.configurers.CsrfConfigurer<HttpSecurity>
$C). ... .disable();
message: "The application fails to protect against Cross-Site Request Forgery (CSRF)\n\
due to disabling Spring's CSRF protection features.\n\nThis vulnerability may\
\ allow attackers to carry out CSRF attacks by crafting \nmalicious links or forms\
\ on external websites. Victims who are tricked into \naccessing these links while\
\ authenticated in your application could inadvertently \nperform actions that\
\ the attacker intends, such as changing user information, \ninitiating transactions,\
\ or altering permissions.\n\nTo remediate this issue, remove the call to `HttpSecurity.csrf().disable()`\
\ or \nremove the custom `CsrfConfigurer`.\n\nFor more information on CSRF protection\
\ in Spring see:\nhttps://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#servlet-csrf\n\
\nAdditionally, consider setting all session cookies to have the `SameSite=Strict`\
\ \nattribute. It should be noted that this may impact usability when sharing\
\ links \nacross other mediums.\nIt is recommended that a two cookie based approach\
\ is taken, as outlined in the\n[Top level\nnavigations](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2)\n\
section of the SameSite RFC.\n\nFor more information on CSRF see OWASP's guide:\n\
https://owasp.org/www-community/attacks/csrf\n"
metadata:
shortDescription: Cross-Site Request Forgery (CSRF)
category: security
cwe: CWE-352
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: Medium
severity: WARNING
- id: java_csrf_rule-UnrestrictedRequestMapping
languages:
- java
patterns:
- pattern-inside: '@RequestMapping(...)
$RETURNTYPE $METHOD(...) { ... }
'
- pattern-not-inside: '@RequestMapping(..., method = $X, ...)
$RETURNTYPE $METHOD(...) { ... }
'
- pattern: 'RequestMapping
'
message: "Detected a method annotated with 'RequestMapping' that does not specify\n\
the HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or\nOPTIONS,\
\ and by default all HTTP methods are allowed when the HTTP method\nis not explicitly\
\ specified. This means that a method that performs state\nchanges could be vulnerable\
\ to CSRF attacks. Cross-Site Request Forgery (CSRF) \nis a security vulnerability\
\ where an attacker tricks a user into performing \nunintended actions on a web\
\ application where they are authenticated. This \ncan lead to unauthorized actions\
\ like changing user settings, transferring \nfunds, or altering passwords, all\
\ without the user's knowledge, by exploiting \nthe trust a web application has\
\ in the user's browser.\n\nTo mitigate, add the 'method' field and specify the\
\ HTTP method (such as \n'RequestMethod.POST').\n\nSecure Code Example:\n```\n\
@RequestMapping(value = \"/path\", method = RequestMethod.POST)\npublic void safe()\
\ {\n // State-changing operations performed within this method.\n}\n```\n"
severity: WARNING
metadata:
shortDescription: Cross-site request forgery (CSRF)
category: security
cwe: CWE-352
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING
references:
- https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING
technology:
- spring
cwe2022-top25: 'true'
cwe2021-top25: 'true'
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Cross-Site Request Forgery (CSRF)
- id: java_xpathi_rule-XpathInjection
languages:
- java
message: "The application processes `XPath` queries with potentially malicious input.\n\
An adversary who is able to control the XPath query could potentially influence\
\ the logic\nof how data is retrieved, processed or even bypass protections.\n\
\nTo mitigate the vulnerability, avoid using user input in XPath queries.\nIf\
\ it cannot be avoided, validate the user input against an allowlist\nof expected\
\ values before using it in the query. \n\nFollowing is an example that demonstrates\
\ how to perform an XPath query \nusing user input validated against an allowlist.\n\
\nSecure code example:\n```\npublic class SecureXPathWithoutResolver {\n\n private\
\ static final List<String> ALLOWED_AUTHORS = List.of(\"Author1\", \"Author2\"\
, \"Author3\");\n\n public static void main(String[] args) {\n try {\n \
\ String userInput = \"Author1\"; // Example user input\n if (ALLOWED_AUTHORS.contains(userInput))\
\ {\n // User input is safe to use\n DocumentBuilderFactory\
\ factory = DocumentBuilderFactory.newInstance();\n DocumentBuilder builder\
\ = factory.newDocumentBuilder();\n Document doc = builder.parse(\"path/to/your/xmlfile.xml\"\
);\n\n XPathFactory xpathFactory = XPathFactory.newInstance();\n \
\ XPath xpath = xpathFactory.newXPath();\n\n // Safely embed the\
\ validated user input into the XPath expression\n String expression\
\ = String.format(\"//books/book[author='%s']\", userInput);\n NodeList\
\ nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);\n\
\n for (int i = 0; i < nodes.getLength(); i++) {\n System.out.println(nodes.item(i).getTextContent());\n\
\ }\n } else {\n throw new IllegalArgumentException(\"\
Input is not allowed.\");\n }\n } catch (Exception e) {\n e.printStackTrace();\n\
\ }\n }\n}\n```\n\nFor more information on XPath Injection see:\n- https://owasp.org/www-community/attacks/XPATH_Injection\n"
metadata:
shortDescription: Improper neutralization of data within XPath expressions ('XPath
Injection')
category: security
cwe: CWE-643
owasp:
- A1:2017-Injection
- A03:2021-Injection
security-severity: Medium
mode: taint
pattern-sources:
- pattern-either:
- pattern: '(HttpServletRequest $REQ).$FUNC(...)
'
- patterns:
- pattern-inside: '$FUNC(..., $VAR, ...) {
...
}
'
- pattern: $VAR
pattern-sinks:
- pattern-either:
- patterns:
- pattern-inside: '(javax.xml.xpath.XPath $XP). ... .evaluate($EXP, ...);
'
- pattern: $EXP
- patterns:
- pattern-inside: '(javax.xml.xpath.XPath $XP). ... .compile($EXP, ...);
'
- pattern: $EXP
pattern-sanitizers:
- patterns:
- pattern-inside: $MAP.getOrDefault($VAR,"...");
- pattern: $VAR
- patterns:
- pattern-either:
- pattern: 'if($VALIDATION){
...
}
'
- patterns:
- pattern-inside: '$A = $VALIDATION;
...
'
- pattern: "if($A){\n ...\n}\n"
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: '$AL.contains(...)
'
- pattern: '$AL.equals(...)
'
severity: ERROR
- id: java_endpoint_rule-ManuallyConstructedURLs
languages:
- java
severity: ERROR
message: "User data flows into the host portion of this manually-constructed URL.\n\
This could allow an attacker to send data to their own server, potentially\nexposing\
\ sensitive data such as cookies or authorization information sent\nwith this\
\ request. They could also probe internal servers or other\nresources that the\
\ server running this code can access. (This is called\nserver-side request forgery,\
\ or SSRF.) Do not allow arbitrary hosts.\nInstead, create an allowlist for approved\
\ hosts hardcode the correct host,\nor ensure that the user data can only affect\
\ the path or parameters.\n\nExample of using allowlist:\n```\nArrayList<String>\
\ allowlist = (ArrayList<String>)\n Arrays.asList(new String[] { \"https://example.com/api/1\"\
, \"https://example.com/api/2\", \"https://example.com/api/3\"});\n\nif(allowlist.contains(url)){\n\
\ ...\n}\n```\n"
options:
interfile: true
metadata:
security-severity: CRITICAL
cwe: CWE-918
owasp:
- A1:2017-Injection
- A10:2021-Server-Side Request Forgery
shortDescription: Detect manually constructed URLs
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
category: security
technology:
- java
- spring
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
impact: MEDIUM
likelihood: MEDIUM
confidence: MEDIUM
interfile: true
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Server-Side Request Forgery (SSRF)
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern-inside: "$METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) {\n ...\n\
}\n"
- pattern-inside: "$METHODNAME(..., @$REQ $TYPE $SOURCE,...) {\n ...\n}\n"
- metavariable-regex:
metavariable: $TYPE
regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean))
- metavariable-regex:
metavariable: $REQ
regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute)
- focus-metavariable: $SOURCE
pattern-sinks:
- pattern-either:
- pattern: new URL($ONEARG)
- patterns:
- pattern-either:
- pattern: '"$URLSTR" + ...
'
- pattern: '"$URLSTR".concat(...)
'
- patterns:
- pattern-inside: 'StringBuilder $SB = new StringBuilder("$URLSTR");
...
'
- pattern: $SB.append(...)
- patterns:
- pattern-inside: '$VAR = "$URLSTR";
...
'
- pattern: $VAR += ...
- patterns:
- pattern: String.format("$URLSTR", ...)
- pattern-not: String.format("$URLSTR", "...", ...)
- patterns:
- pattern-inside: 'String $VAR = "$URLSTR";
...
'
- pattern: String.format($VAR, ...)
- metavariable-regex:
metavariable: $URLSTR
regex: http(s?)://%(v|s|q).*
pattern-sanitizers:
- patterns:
- pattern-either:
- pattern: "if($VALIDATION){\n ...\n new URL($ONEARG);\n ...\n} \n"
- pattern: "$A = $VALIDATION;\n...\nif($A){\n ...\n new URL($ONEARG);\n ...\n\
}\n"
- metavariable-pattern:
metavariable: $VALIDATION
pattern-either:
- pattern: "$AL.contains(...) \n"
- pattern: '$AL.indexOf(...) != -1
'
- id: java_traversal_rule-RelativePathTraversal
languages:
- java
message: "Detected user input controlling a file path. An attacker could control\n\
the location of this file, to include going backwards in the directory\nwith '../'.\
\ \n\nTo address this, ensure that user-controlled variables in file\npaths are\
\ sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...)\
\ to only retrieve the file\nname from the path.\n\nExample of using `org.apache.commons.io.FilenameUtils.getName(...)`\
\ to \nonly retrieve the file name from the path\n```\nString fileName = org.apache.commons.io.FilenameUtils.getName(userControlledInput);\n\
File file = new File(\"/path/to/directory/\" + fileName);\n```\n"
options:
interfile: true
severity: ERROR
metadata:
cwe: CWE-23
shortDescription: Relative Path Traversal
owasp:
- A01:2021-Broken Access Control
- A5:2017-Broken Access Control
references:
- https://owasp.org/www-community/attacks/Path_Traversal
category: security
security-severity: CRITICAL
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern-inside: "$METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) {\n ...\n\
}\n"
- pattern-inside: "$METHODNAME(..., @$REQ $TYPE $SOURCE,...) {\n ...\n}\n"
- metavariable-regex:
metavariable: $TYPE
regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean))
- metavariable-regex:
metavariable: $REQ
regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute)
- focus-metavariable: $SOURCE
pattern-sinks:
- patterns:
- pattern-either:
- pattern: new File(...)
- pattern: new java.io.File(...)
- pattern: new FileReader(...)
- pattern: new java.io.FileReader(...)
- pattern: new FileInputStream(...)
- pattern: new java.io.FileInputStream(...)
- pattern: (Paths $PATHS).get(...)
- patterns:
- pattern: '$CLASS.$FUNC(...)
'
- metavariable-regex:
metavariable: $FUNC
regex: ^(getResourceAsStream|getResource)$
- patterns:
- pattern-either:
- pattern: new ClassPathResource($FILE, ...)
- pattern: ResourceUtils.getFile($FILE, ...)
- pattern: new FileOutputStream($FILE, ...)
- pattern: new java.io.FileOutputStream($FILE, ...)
- pattern: new StreamSource($FILE, ...)
- pattern: new javax.xml.transform.StreamSource($FILE, ...)
- pattern: FileUtils.openOutputStream($FILE, ...)
- focus-metavariable: $FILE
pattern-sanitizers:
- pattern: org.apache.commons.io.FilenameUtils.getName(...)
- id: java_cookie_rule-CookieHTTPOnly
languages:
- java
patterns:
- pattern-either:
- pattern: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(false);
- patterns:
- pattern-not-inside: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(...); ...
- pattern: $RESPONSE.addCookie($COOKIE);
message: 'The `HttpOnly` attribute when set to `true` protects the cookie value
from being accessed by
client side JavaScript such
as reading the `document.cookie` values. By enabling this protection, a website
that is
vulnerable to
Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing
the cookie
value from JavaScript.
Example of protecting a `Cookie`:
```
// Create an HttpOnly cookie.
Cookie someCookie = new Cookie("SomeCookieName", "SomeValue");
// Set HttpOnly flag to true
someCookie.setHttpOnly(true);
```
For more information see:
https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setHttpOnly-boolean-
Session cookies should be configured with the following security directives:
- [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)
- [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)
- [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite)
'
severity: WARNING
metadata:
shortDescription: Sensitive cookie without 'HttpOnly' flag
category: security
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
cwe: CWE-1004
technology:
- java
security-severity: Low
- id: java_deserialization_rule-SnakeYamlConstructor
languages:
- java
patterns:
- pattern: '$Y = new org.yaml.snakeyaml.Yaml();
...
$Y.load(...);
'
message: "The application uses SnakeYAML org.yaml.snakeyaml.Yaml() constructor \n\
with no arguments, which is vulnerable to deserialization attacks. \nWhen Yaml()\
\ (no-argument constructor) is used, SnakeYAML uses the \ndefault Constructor\
\ which can instantiate any Java object during \ndeserialization. This is risky\
\ because an attacker could craft malicious \nYAML files to execute arbitrary\
\ code or perform unauthorized actions.\n\nTo mitigate the issue and to safely\
\ use SnakeYaml to parse YAML data, \nalways make sure to only ever use a Yaml\
\ instance that is constructed \neither with a SafeConstructor or an instance\
\ constructed with a \nConstructor specifying a specific class. \n\nPlease note,\
\ if you want to use Constructor with a specific target class\nas a mitigation\
\ criteria, ensure that snakeyaml version is 2.0 or higher\nas Constructor class\
\ is vulnerable in snakeyaml versions lower than 2.0.\nRefer - https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2\n\
\nSecure Code Examples:\n```\npublic void safeConstructorLoad(String toLoad) {\n\
\ // Configure LoaderOptions for safe deserialization\n LoaderOptions loaderOptions\
\ = new LoaderOptions();\n loaderOptions.setAllowDuplicateKeys(false);\n loaderOptions.setMaxAliasesForCollections(50);\n\
\n Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptipon()));\n yaml.load(toLoad);\n\
}\n\npublic void customConstructorLoad(String toLoad, Class<?> goodClass) {\n\
\ // Use Constructor with a specific target class\n LoaderOptions loaderOptions\
\ = new LoaderOptions();\n Constructor customConstructor = new Constructor(goodClass,\
\ loaderOptions);\n\n Yaml yaml = new Yaml(customConstructor);\n yaml.load(toLoad);\n\
}\n```\n"
metadata:
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
category: security
shortDescription: Deserialization of untrusted data
security-severity: HIGH
references:
- https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/#snakeyaml-deserialization-vulnerability
technology:
- snakeyaml
likelihood: LOW
impact: HIGH
confidence: LOW
severity: ERROR
- id: java_deserialization_rule-InsecureJmsDeserialization
languages:
- java
patterns:
- pattern-inside: "class $JMS_LISTENER implements MessageListener {\n ...\n public\
\ void onMessage(Message $JMS_MSG) {\n ...\n }\n}\n"
- pattern: $Y.getObject(...);
message: "Deserialization of untrusted JMS ObjectMessage can lead to arbitrary \n\
code execution. This vulnerability occurs when `ObjectMessage.getObject()` \n\
is called to deserialize the payload of an ObjectMessage, potentially \nallowing\
\ remote attackers to execute arbitrary code with the permissions \nof the JMS\
\ MessageListener application. \n\nTo mitigate the issue, avoid deserialization\
\ of untrusted data and \nconsider alternative message formats or explicit whitelisting\
\ of \nallowable classes for deserialization.\n\nTo implement allowlisting, override\
\ the ObjectInputStream#resolveClass() \nmethod to limit deserialization to allowed\
\ classes only. This prevents \ndeserialization of any class except those explicitly\
\ permitted, such as \nin the following example that restricts deserialization\
\ to the Bicycle \nclass only:\n\n```\n// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html\n\
public class LookAheadObjectInputStream extends ObjectInputStream {\n public\
\ LookAheadObjectInputStream(InputStream inputStream) throws IOException {\n \
\ super(inputStream);\n }\n /**\n * Only deserialize instances\
\ of our expected Bicycle class\n */\n @Override\n protected Class<?>\
\ resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException\
\ {\n if (!desc.getName().equals(Bicycle.class.getName())) {\n \
\ throw new InvalidClassException(\"Unauthorized deserialization attempt\"\
, desc.getName());\n }\n return super.resolveClass(desc);\n }\n\
}\n```\n"
metadata:
cwe: CWE-502
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
category: security
shortDescription: Deserialization of untrusted data
security-severity: High
references:
- https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf
technology:
- java
cwe2022-top25: 'true'
cwe2021-top25: 'true'
subcategory:
- vuln
likelihood: LOW
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- 'Insecure Deserialization '
severity: ERROR
- id: java_deserialization_rule-ServerDangerousObjectDeserialization
languages:
- java
patterns:
- pattern-inside: "interface $INTERFACE extends Remote {\n ...\n}\n"
- pattern: '$RETURNTYPE $METHOD($PARAMTYPE $PARAM) throws RemoteException;
'
- metavariable-pattern:
metavariable: $PARAMTYPE
language: generic
patterns:
- pattern-not: String
- pattern-not: java.lang.String
- pattern-not: boolean
- pattern-not: Boolean
- pattern-not: java.lang.Boolean
- pattern-not: byte
- pattern-not: Byte
- pattern-not: java.lang.Byte
- pattern-not: char
- pattern-not: Character
- pattern-not: java.lang.Character
- pattern-not: double
- pattern-not: Double
- pattern-not: java.lang.Double
- pattern-not: float
- pattern-not: Float
- pattern-not: java.lang.Float
- pattern-not: int
- pattern-not: Integer
- pattern-not: java.lang.Integer
- pattern-not: long
- pattern-not: Long
- pattern-not: java.lang.Long
- pattern-not: short
- pattern-not: Short
- pattern-not: java.lang.Short
severity: WARNING
metadata:
cwe: CWE-502
shortDescription: Deserialization of untrusted data
owasp:
- A8:2017-Insecure Deserialization
- A08:2021-Software and Data Integrity Failures
references:
- https://frohoff.github.io/appseccali-marshalling-pickles/
- https://book.hacktricks.xyz/network-services-pentesting/1099-pentesting-java-rmi
- https://youtu.be/t_aw1mDNhzI
- https://github.com/qtc-de/remote-method-guesser
- https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java#L303C4-L331
- https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290/
category: security
security-severity: MEDIUM
technology:
- rmi
cwe2022-top25: 'true'
cwe2021-top25: 'true'
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- 'Insecure Deserialization '
message: "This application uses Java RMI (Remote Method Invocation) interfaces \n\
that declare methods with parameters of arbitrary objects \n('$PARAMTYPE $PARAM')\
\ that could lead to insecure deserialization \nvulnerabilities. Insecure deserialization\
\ occurs when an application \ndeserializes data from untrusted sources without\
\ proper sanitization, \npotentially leading to arbitrary code execution, denial\
\ of service attacks, \nand other critical vulnerabilities.\n\nJava RMI allows\
\ for remote communication between applications by \ninvoking methods on remote\
\ objects. When complex objects are used \nas parameters in RMI method declarations,\
\ there is \na risk that a malicious actor could exploit the deserialization \n\
process to execute arbitrary code on the server. This vulnerability \nis especially\
\ significant if the parameter types are not among the safe, \nimmutable types\
\ like String, Integer, etc.\n\nTo mitigate this vulnerability, use an integer\
\ ID to look up your \nobject, or consider alternative serialization schemes such\
\ as JSON.\n\nSecure Code Example:\n```\nimport java.rmi.Remote;\nimport java.rmi.RemoteException;\n\
\npublic interface SafeTicketService extends Remote {\n // Using String, which\
\ is a safe, immutable type\n boolean registerTicket(String ticketID) throws\
\ RemoteException;\n\n // Using primitive data types and wrappers, which are\
\ safe\n void visitTalk(int talkID) throws RemoteException;\n void poke(Integer\
\ attendeeID) throws RemoteException;\n}\n```\n"
- id: rules_lgpl_oc_other_rule-ios-self-signed-ssl
pattern-either:
- pattern: canAuthenticateAgainstProtectionSpace
- pattern: continueWithoutCredentialForAuthenticationChallenge
- pattern: kCFStreamSSLAllowsExpiredCertificates
- pattern: kCFStreamSSLAllowsAnyRoot
- pattern: kCFStreamSSLAllowsExpiredRoots
- patterns:
- pattern: validatesSecureCertificate = $NO
- metavariable-regex:
metavariable: $NO
regex: NO|no
- patterns:
- pattern: allowInvalidCertificates = $YES
- metavariable-regex:
metavariable: $YES
regex: YES|yes
paths:
include:
- '**/*.m'
message: "App allows self signed or invalid SSL certificates. App is \nvulnerable\
\ to MITM attacks. If the app does not verify the \nauthenticity of the server's\
\ SSL certificate, an attacker could \nimpersonate the server and intercept sensitive\
\ data transmitted \nbetween the app and the server.\nTo fix these security issues,\
\ you should ensure proper SSL \ncertificate validation in your Objective-C code.\
\ Here's how you \ncan do it:\n```\n- (void)loadSecureURL {\n NSURL *url = [NSURL\
\ URLWithString:@\"https://example.com\"];\n NSURLRequest *request = [NSURLRequest\
\ requestWithURL:url];\n\n // Create session configuration\n NSURLSessionConfiguration\
\ *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];\n\
\ configuration.TLSMinimumSupportedProtocol = kTLSProtocol12;\n\n // Create\
\ session with configuration\n NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];\n\
\n // Create data task\n NSURLSessionDataTask *task = [session dataTaskWithRequest:request\
\ completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response,\
\ NSError * _Nullable error) {\n if (error) {\n NSLog(@\"Error loading\
\ URL: %@\", error);\n // Handle error\n } else {\n //\
\ Handle response\n NSLog(@\"Response: %@\", response);\n }\n }];\n\
\n // Start task\n [task resume];\n}\n\n```\n"
languages:
- generic
severity: ERROR
metadata:
category: security
cwe: CWE-676
shortDescription: Use of potentially dangerous function
owasp:
- A9:2017-Using Components with Known Vulnerabilities
- A06:2021-Vulnerable and Outdated Components
security-severity: CRITICAL
- id: rules_lgpl_oc_other_rule-ios-webview-ignore-ssl
pattern-either:
- pattern: allowsAnyHTTPSCertificateForHost
- patterns:
- pattern: loadingUnvalidatedHTTPSPage = $YES
- metavariable-regex:
metavariable: $YES
regex: YES|yes
- patterns:
- pattern: allowsAnyHTTPSCertificate = $YES
- metavariable-regex:
metavariable: $YES
regex: YES|yes
paths:
include:
- '**/*.m'
message: "UIWebView in App ignore SSL errors and accept any SSL Certificate. \n\
App is vulnerable to MITM attacks. If the app does not verify the \nauthenticity\
\ of the server's SSL certificate, an attacker could \nimpersonate the server\
\ and intercept sensitive data transmitted \nbetween the app and the server.\n\
To fix these security issues, you should ensure proper SSL certificate \nvalidation\
\ in your Objective-C code. Here's how you can do it:\n```\n- (void)loadSecureURL\
\ {\n NSURL *url = [NSURL URLWithString:@\"https://example.com\"];\n NSURLRequest\
\ *request = [NSURLRequest requestWithURL:url];\n \n // Create session configuration\n\
\ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];\n\
\ configuration.TLSMinimumSupportedProtocol = kTLSProtocol12;\n \n // Create\
\ session with configuration\n NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];\n\
\ \n // Create data task\n NSURLSessionDataTask *task = [session dataTaskWithRequest:request\
\ completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response,\
\ NSError * _Nullable error) {\n if (error) {\n NSLog(@\"Error loading\
\ URL: %@\", error);\n // Handle error\n } else {\n //\
\ Handle response\n NSLog(@\"Response: %@\", response);\n }\n }];\n\
\ \n // Start task\n [task resume];\n}\n```\n"
languages:
- generic
severity: ERROR
metadata:
category: security
cwe: CWE-295
shortDescription: Improper certificate validation
owasp:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
security-severity: CRITICAL
- id: python_crypto_rule-HTTPConnectionPool
languages:
- python
pattern-either:
- pattern: urllib3.HTTPConnectionPool(...)
- pattern: urllib3.connectionpool.HTTPConnectionPool(...)
message: "The application is using HTTPConnectionPool method. This method transmits\n\
data in cleartext, which is vulnerable to MITM (Man in the middle)\nattacks. In\
\ MITM attacks, the data transmitted over the unencrypted\nconnection can be intercepted,\
\ read and/or modified by unauthorized\nparties which can lead to data integrity\
\ and confidentiality loss. \n\nTo mitigate this issue, use HTTPSConnectionPool\
\ instead, which encrypts \ncommunications and enhances security.\n\nSecure Code\
\ Example:\n```\nimport urllib3\nspool = urllib3.connectionpool.HTTPSConnectionPool(\"\
example.com\")\n```\n"
metadata:
category: security
cwe: CWE-319
shortDescription: Cleartext transmission of sensitive information
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
security-severity: MEDIUM
references:
- https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool
technology:
- python
subcategory:
- audit
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
severity: WARNING
- id: python_escaping_rule-django
languages:
- python
message: 'Cross Site Scripting (XSS) is an attack which exploits a web application
or system to treat
user input
as markup or script code. It is important to encode the data depending on the
specific context
it
is used in. There are at least six context types:
- Inside HTML tags `<div>context 1</div>`
- Inside attributes: `<div class="context 2"></div>`
- Inside event attributes `<button onclick="context 3">button</button>`
- Inside script blocks: `<script>var x = "context 4"</script>`
- Unsafe element HTML assignment: `element.innerHTML = "context 5"`
- Inside URLs: `<iframe src="context 6"></iframe><a href="context 6">link</a>`
Script blocks alone have multiple ways they need to be encoded. Extra care must
be taken if
user input
is ever output inside of script tags.
User input that is displayed within the application must be encoded, sanitized
or validated
to ensure it cannot be treated as HTML or executed as Javascript code. Care must
also be
taken
to not mix server-side templating with client-side templating, as the server-side
templating
will
not encode things like {{ 7*7 }} which may execute client-side templating features.
It is _NOT_ advised to encode user input prior to inserting into a data store.
The data will
need to be
encoded depending on context of where it is output. It is much safer to force
the displaying
system to
handle the encoding and not attempt to guess how it should be encoded.
Consider using
[format_html](https://docs.djangoproject.com/en/4.2/ref/utils/#django.utils.html.format_html)
instead of
the `django.utils.safestring` methods.
Example using `format_html`:
```
# Use format_html to create an HTML link, using href as the parameter
# which will be encoded automatically
format_html("<li><a href=''{}''>Some Link</a></li>", href)
```
For more information on XSS see OWASP:
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
'
metadata:
cwe: CWE-79
owasp:
- A7:2017-Cross-Site Scripting (XSS)
- A03:2021-Injection
category: security
shortDescription: Improper neutralization of input during web page generation
('Cross-site Scripting')
security-severity: Medium
patterns:
- pattern-not-inside: django.utils.html.format_html(...)
- pattern-either:
- patterns:
- pattern: django.utils.safestring.SafeText(...)
- pattern-not: django.utils.safestring.SafeText("...")
- patterns:
- pattern: django.utils.safestring.SafeUnicode(...)
- pattern-not: django.utils.safestring.SafeUnicode("...")
- patterns:
- pattern: django.utils.safestring.SafeString(...)
- pattern-not: django.utils.safestring.SafeString("...")
- patterns:
- pattern: django.utils.safestring.SafeBytes(...)
- pattern-not: django.utils.safestring.SafeBytes("...")
- patterns:
- pattern: django.utils.safestring.mark_safe(...)
- pattern-not: django.utils.safestring.mark_safe("...")
severity: WARNING
- id: python_django_rule-django-raw-used
message: "SQL Injections are a critical type of vulnerability that can lead to data\
\ \nor system compromise. By dynamically generating SQL query strings, user \n\
input may be able to influence the logic of the SQL statement. \nThis could lead\
\ to an adversary accessing information they should not \nhave access to, or in\
\ some circumstances, being able to execute OS functionality\nor code.\n\nReplace\
\ all dynamically generated SQL queries with parameterized queries. \nIn situations\
\ where dynamic queries must be created, never use direct user input,\nbut instead\
\ use a map or dictionary of valid values and resolve them using a user \nsupplied\
\ key.\n\nFor example, some database drivers do not allow parameterized queries\
\ for \n`>` or `<` comparison operators. In these cases, do not use a user supplied\
\ \n`>` or `<` value, but rather have the user supply a `gt` or `lt` value. \n\
The alphabetical values are then used to look up the `>` and `<` values to be\
\ used \nin the construction of the dynamic query. The same goes for other queries\
\ where \ncolumn or table names are required but cannot be parameterized.\n\n\
Data that is possible user-controlled from a python request is passed\nto `raw()`\
\ function. To remediate this issue, use django's QuerySets, \nwhich are built\
\ with query parameterization and therefore not vulnerable \nto sql injection.\
\ For example, you could use `Entry.objects.filter(date=2006)`\n\nIf for some\
\ reason this is not feasible, ensure calls including user-supplied \ndata pass\
\ it in to the `params` parameter of the `raw()` method.\nBelow is an example\
\ using `raw()`, passing in user-supplied data as `params`. \nThis will treat\
\ the query as a parameterized query and `params` as strictly data, \npreventing\
\ any possibility of SQL Injection.\n\n```\ndef test(request):\n uname = request.GET[\"\
username\"] \n res = User.objects.raw('SELECT * FROM myapp_user WHERE username\
\ = %s', (uname,))\n```\n\nFor more information on QuerySet see:\n- https://docs.djangoproject.com/en/5.0/ref/models/querysets/\n\
\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n"
metadata:
cwe: CWE-89
owasp:
- A1:2017-Injection
- A03:2021-Injection
category: security
shortDescription: Improper neutralization of special elements used in an SQL Command
('SQL Injection')
security-severity: High
languages:
- python
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern: $PARAM
- pattern-inside: "def $VIEW(...,$PARAM,...):\n ...\n return ... \n"
pattern-sinks:
- patterns:
- pattern: $QUERY
- pattern-inside: $MODEL.objects.raw($QUERY, ... )
- id: python_django_rule-django-rawsql-used
languages:
- python
message: "SQL Injections are a critical type of vulnerability that can lead to data\
\ or system compromise. By \ndynamically generating SQL query strings, user input\
\ may be able to influence the logic of the SQL \nstatement. This could lead to\
\ an adversary accessing information they should not have access to, or in\nsome\
\ circumstances, being able to execute OS functionality or code.\n\nReplace all\
\ dynamically generated SQL queries with parameterized queries. In situations\
\ where dynamic \nqueries must be created, never use direct user input, but instead\
\ use a map or dictionary of valid values \nand resolve them using a user supplied\
\ key.\n\nFor example, some database drivers do not allow parameterized queries\
\ for `>` or `<` comparison operators. \nIn these cases, do not use a user supplied\
\ `>` or `<` value, but rather have the user supply a `gt` or `lt` \nvalue. The\
\ alphabetical values are then used to look up the `>` and `<` values to be used\
\ in the \nconstruction of the dynamic query. The same goes for other queries\
\ where column or table names are required \nbut cannot be parameterized.\n\n\
To remediate this issue, do not use `raw` or `RawSQL` but use other `QuerySet`\
\ methods to achieve the same\ngoals. If for some reason this is not feasible,\
\ ensure calls including user-supplied data pass it in to \nthe `params` parameter\
\ of the `RawSQL` method.\n\nWhile not recommended due to [potential SQL Injection](https://docs.djangoproject.com/en/5.0/ref/models/expressions/#raw-sql-expressions),\
\ below is an example using `RawSQL`.\nPassing in user-supplied data as a `param`\
\ which will escape the input:\n\n```\n# If dealing with integer based user input,\
\ restrict the values to integers only using the\n# path configuration: path('/someview/<int:user_supplied_id>',\
\ views.some_view, name='someview'),\n\n# views.py\ndef some_view(request, user_supplied_id):\n\
\ # Never use string interpolation in the `sql` parameter.\n # Never quote the\
\ `%s` string format such as `... where id='%s'` as this could lead to SQL Injection.\n\
\ # Pass the user supplied data only in the `params` parameter.\n for obj in\
\ DBObject.objects.all().annotate(\n val=RawSQL(sql=\"select id from some_secondary_table\
\ where id=%s\", params=[user_supplied_id])):\n # Work with the results from\
\ the query\n # ...\n```\n\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\n\
\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n"
metadata:
cwe: CWE-89
owasp:
- A1:2017-Injection
- A03:2021-Injection
category: security
shortDescription: Improper neutralization of special elements used in an SQL Command
('SQL Injection')
security-severity: CRITICAL
mode: taint
pattern-sources:
- patterns:
- pattern: $PARAM
- pattern-inside: "def $VIEW(...,$PARAM,...):\n ...\n return ...\n"
pattern-sinks:
- patterns:
- pattern: $QUERY
- pattern-inside: django.db.models.expressions.RawSQL($QUERY, ... )
severity: ERROR
- id: python_pyramid_rule-pyramid-csrf-origin-check
patterns:
- pattern-inside: '$CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN,
...)
'
- pattern: '$CHECK_ORIGIN
'
- metavariable-comparison:
metavariable: $CHECK_ORIGIN
comparison: $CHECK_ORIGIN == False
message: "Automatic check of the referrer for cross-site request forgery tokens\n\
has been explicitly disabled globally, which might leave views unprotected\nwhen\
\ an unsafe CSRF storage policy is used. By passing `check_origin=False` \nto\
\ `set_default_csrf_options()` method, you opt out of checking the origin \nof\
\ the domain in the referrer header or the origin header, which can make \nthe\
\ application vulnerable to CSRF attacks, specially if CSRF token is not \nproperly\
\ implemented.\nCSRF attacks are a type of exploit where an attacker tricks a\
\ user into \nexecuting unwanted actions on a web application in which they are\
\ authenticated. \nIf a user is logged into a web application, an attacker could\
\ create a malicious \nlink or script on another site that causes the user's browser\
\ to make a request \nto the web application, carrying out an action without the\
\ user's consent.\n\nTo mitigate this vulnerability, use \n'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)'\n\
to turn the automatic check for all unsafe methods (per RFC2616).\n\nSecure Code\
\ Example:\n```\ndef safe(config):\n config.set_csrf_storage_policy(CookieCSRFStoragePolicy())\n\
\ config.set_default_csrf_options(check_origin=True)\n```\n"
languages:
- python
severity: WARNING
metadata:
shortDescription: Cross-site request forgery (CSRF)
category: security
cwe: CWE-352
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
security-severity: MEDIUM
technology:
- pyramid
references:
- https://owasp.org/Top10/A01_2021-Broken_Access_Control
- https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html
cwe2022-top25: 'true'
cwe2021-top25: 'true'
subcategory:
- vuln
likelihood: LOW
impact: LOW
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Cross-Site Request Forgery (CSRF)
- id: python_flask_rule-flask-open-redirect
languages:
- python
patterns:
- pattern-inside: "@$APP.route(...)\ndef $X(...):\n ...\n"
- pattern-not-inside: "@$APP.route(...)\ndef $X(...):\n ...\n if <... werkzeug.urls.url_parse($V)\
\ ...>:\n ...\n"
- pattern-either:
- pattern: flask.redirect(<... flask.request.$W.get(...) ...>, ...)
- pattern: flask.redirect(<... flask.request.$W[...] ...>, ...)
- pattern: flask.redirect(<... flask.request.$W(...) ...>, ...)
- pattern: flask.redirect(<... flask.request.$W ...>, ...)
- pattern: '$V = flask.request.$W.get(...)
...
flask.redirect(<... $V ...>, ...)
'
- pattern: '$V = flask.request.$W[...]
...
flask.redirect(<... $V ...>, ...)
'
- pattern: '$V = flask.request.$W(...)
...
flask.redirect(<... $V ...>, ...)
'
- pattern: '$V = flask.request.$W
...
flask.redirect(<... $V ...>, ...)
'
- pattern-not: flask.redirect(flask.request.path)
- pattern-not: flask.redirect(flask.request.path + ...)
- pattern-not: flask.redirect(f"{flask.request.path}...")
message: "Data from request is passed to redirect(). This is an open redirect and\
\ could be exploited. Consider using 'url_for()' to generate links to known locations.\
\ If you must use a URL to unknown pages, consider using 'urlparse()' or similar\
\ and checking if the 'netloc' property is the same as your site's host name.\
\ For example:\n\n Example:\n ```python\n from flask import Flask, request,\
\ redirect, url_for\n from urllib.parse import urlparse\n\n app = Flask(__name__)\n\
\n @app.route('/login')\n def login():\n next = request.args.get('next')\n\
\ if not next:\n next = url_for('index')\n if urlparse(next).netloc\
\ != urlparse(request.url).netloc:\n return redirect(url_for('index'))\n\
\ return redirect(next)\n ```\n See the references for more information."
metadata:
cwe: CWE-601
shortDescription: URL redirection to untrusted site ('Open Redirect')
owasp:
- A01:2021-Broken Access Control
- A5:2017-Broken Access Control
category: security
security-severity: MEDIUM
references: '- https://flask-login.readthedocs.io/en/latest/#login-example
- https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html#dangerous-url-redirect-example-1
- https://docs.python.org/3/library/urllib.parse.html#url-parsing
'
technology:
- flask
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
severity: WARNING
- id: python_flask_rule-path-traversal-open
languages:
- python
severity: ERROR
message: "Found request data in a call to 'open'. An attacker can manipulate this\
\ input to access files outside the intended \ndirectory. This can lead to unauthorized\
\ access to sensitive files or directories. To prevent path traversal attacks,\
\ \navoid using user-controlled input in file paths. If you must use user-controlled\
\ input, validate and sanitize the \ninput to ensure it does not contain any path\
\ traversal sequences. For example, you can use the `os.path.join` function \n\
to safely construct file paths or validate that the absolute path starts with\
\ the directory which is whitelisted for \naccessing file. The following code\
\ snippet demonstrates how to validate a file path from user-controlled input:\n\
```\nimport os\n\ndef safe_open_file(filename, base_path):\n # Resolve the absolute\
\ path of the user-supplied filename\n absolute_path = os.path.abspath(filename)\n\
\n # Check that the absolute path starts with the base path\n if not absolute_path.startswith(base_path):\n\
\ raise ValueError(\"Invalid file path\")\n\n return open(absolute_path,\
\ 'r')\n```\nFor more information, see the OWASP Path Traversal page: https://owasp.org/www-community/attacks/Path_Traversal\n"
metadata:
cwe: CWE-22
shortDescription: Improper Limitation of a Pathname to a Restricted Directory
('Path Traversal')
owasp:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
category: security
security-severity: CRITICAL
references:
- https://owasp.org/www-community/attacks/Path_Traversal
technology:
- flask
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
pattern-either:
- patterns:
- pattern: open(...)
- pattern-either:
- pattern-inside: "@$APP.route($ROUTE, ...)\ndef $FUNC(..., $ROUTEVAR, ...):\n\
\ ...\n open(..., <... $ROUTEVAR ...>, ...)\n"
- pattern-inside: "@$APP.route($ROUTE, ...)\ndef $FUNC(..., $ROUTEVAR, ...):\n\
\ ...\n with open(..., <... $ROUTEVAR ...>, ...) as $FD:\n ...\n"
- pattern-inside: "@$APP.route($ROUTE, ...)\ndef $FUNC(..., $ROUTEVAR, ...):\n\
\ ...\n $INTERIM = <... $ROUTEVAR ...>\n ...\n open(..., <... $INTERIM\
\ ...>, ...)\n"
- pattern: open(..., <... flask.request.$W.get(...) ...>, ...)
- pattern: open(..., <... flask.request.$W[...] ...>, ...)
- pattern: open(..., <... flask.request.$W(...) ...>, ...)
- pattern: open(..., <... flask.request.$W ...>, ...)
- patterns:
- pattern-inside: '$INTERIM = <... flask.request.$W.get(...) ...>
...
open(<... $INTERIM ...>, ...)
'
- pattern: open(...)
- patterns:
- pattern-inside: '$INTERIM = <... flask.request.$W[...] ...>
...
open(<... $INTERIM ...>, ...)
'
- pattern: open(...)
- patterns:
- pattern-inside: '$INTERIM = <... flask.request.$W(...) ...>
...
open(<... $INTERIM ...>, ...)
'
- pattern: open(...)
- patterns:
- pattern-inside: '$INTERIM = <... flask.request.$W ...>
...
open(<... $INTERIM ...>, ...)
'
- pattern: open(...)
- patterns:
- pattern-inside: "$INTERIM = <... flask.request.$W.get(...) ...>\n...\nwith open(<...\
\ $INTERIM ...>, ...) as $F:\n ...\n"
- pattern: open(...)
- patterns:
- pattern-inside: "$INTERIM = <... flask.request.$W[...] ...>\n...\nwith open(<...\
\ $INTERIM ...>, ...) as $F:\n ...\n"
- pattern: open(...)
- patterns:
- pattern-inside: "$INTERIM = <... flask.request.$W(...) ...>\n...\nwith open(<...\
\ $INTERIM ...>, ...) as $F:\n ...\n"
- pattern: open(...)
- patterns:
- pattern-inside: "$INTERIM = <... flask.request.$W ...>\n...\nwith open(<...\
\ $INTERIM ...>, ...) as $F:\n ...\n"
- pattern: open(...)
- id: python_flask_rule-tainted-sql-string
languages:
- python
message: "Detected user input used to manually construct a SQL string. This is usually\n\
bad practice because manual construction could accidentally result in a SQL\n\
injection. An attacker could use a SQL injection to steal or modify contents\n\
of the database. Instead, use a parameterized query which is available\nby default\
\ in most database engines. Alternatively, consider using an\nobject-relational\
\ mapper (ORM) such as SQLAlchemy which will protect your queries.\n\nSQL Injections\
\ are a critical type of vulnerability that can lead to data \nor system compromise.\
\ By dynamically generating SQL query strings, user \ninput may be able to influence\
\ the logic of an SQL statement. \nThis could lead to an malicious parties accessing\
\ information they should not \nhave access to, or in some circumstances, being\
\ able to execute OS functionality\nor code.\n\nReplace all dynamically generated\
\ SQL queries with parameterized queries. \nIn situations where dynamic queries\
\ must be created, never use direct user input,\nbut instead use a map or dictionary\
\ of valid values and resolve them using a user \nsupplied key.\n\nFor example,\
\ some database drivers do not allow parameterized queries for \n`>` or `<` comparison\
\ operators. In these cases, do not use a user supplied \n`>` or `<` value, but\
\ rather have the user supply a `gt` or `lt` value. \nThe alphabetical values\
\ are then used to look up the `>` and `<` values to be used \nin the construction\
\ of the dynamic query. The same goes for other queries where \ncolumn or table\
\ names are required but cannot be parameterized.\nData that is possible user-controlled\
\ from a python request is passed\nto `execute()` function. To remediate this\
\ issue, use SQLAlchemy statements\nwhich are built with query parameterization\
\ and therefore not vulnerable \nto sql injection.\n\nIf for some reason this\
\ is not feasible, ensure calls including user-supplied \ndata pass it in to the\
\ `params` parameter of the `execute()` method.\nBelow is an example using `execute()`,\
\ passing in user-supplied data as `params`. \nThis will treat the query as a\
\ parameterized query and `params` as strictly data, \npreventing any possibility\
\ of SQL Injection.\n\n```\nname = request.args.get('name')\nreq = text('SELECT\
\ * FROM student WHERE firstname = :x')\nresult = db.session.execute(req, {\"\
x\":name})\n```\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\n\
For more information on SQL Injections see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n"
metadata:
security-severity: High
cwe: CWE-89
owasp:
- A1:2017-Injection
- A03:2021-Injection
category: security
shortDescription: Improper neutralization of special elements used in an SQL Command
('SQL Injection')
mode: taint
pattern-sources:
- pattern-either:
- pattern: flask.request.$ANYTHING
- patterns:
- pattern-inside: "@$APP.route(...)\ndef $FUNC(..., $ROUTEVAR, ...):\n ...\n"
- pattern: $ROUTEVAR
pattern-sinks:
- patterns:
- pattern-either:
- pattern: '<... "$QUERYLIKE" ...>
'
- metavariable-regex:
metavariable: $QUERYLIKE
regex: .*\b(?i)(SELECT .+ FROM|WHERE|DELETE FROM|INSERT INTO| CREATE TABLE|UPDATE
.+ SET|ALTER TABLE|ALTER COLUMN|DROP COLUMN|DROP TABLE|ORDER BY)\b.*
severity: ERROR
- id: python_jwt_rule-jwt-none-alg
languages:
- python
message: 'Detected use of the ''none'' algorithm in a JWT token.
The ''none'' algorithm assumes the integrity of the token has already
been verified. This would allow a malicious actor to forge a JWT token
that will automatically be verified. Do not explicitly use the ''none''
algorithm. Instead, use an algorithm such as ''HS256''.
'
metadata:
cwe: CWE-327
shortDescription: Use of a Broken or Risky Cryptographic Algorithm
owasp:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
category: security
security-severity: MEDIUM
source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
technology:
- jwt
references:
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
severity: ERROR
pattern-either:
- pattern: jwt.encode(...,algorithm="none",...)
- pattern: jwt.decode(...,algorithms=[...,"none",...],...)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment