PHP Coding Violations
Cyclopt analyzes your PHP code to identify coding and security violations. Each check below lists its Rule ID, a description, a default severity, and its category.
Use a check's Rule ID to silence a finding in code with a cyclopt-ignore comment, or to exclude it project-wide in the configuration file.
Commenting
Long Description Capitalize
Rule ID: Generic.Commenting.DocComment.LongNotCapital
Description: Doc comment long description must start with a capital letter
/**
* Short description.
*
* this is the long description.
*/
/**
* Short description.
*
* This is the long description.
*/
Missing Short Description
Rule ID: Generic.Commenting.DocComment.MissingShort
Description: Missing short description in doc comment
/**
* @param string $name User name.
*/
function greet($name)
{
}
/**
* Greets a user.
*
* @param string $name User name.
*/
function greet($name)
{
}
Non Parameter Group
Rule ID: Generic.Commenting.DocComment.NonParamGroup
Description: Tag @return cannot be grouped with parameter tags in a doc comment
/**
* Adds numbers.
*
* @param int $a First.
* @return int
*/
function add($a)
{
return $a;
}
/**
* Adds numbers.
*
* @param int $a First.
*
* @return int
*/
function add($a)
{
return $a;
}
Short Description Capitalize
Rule ID: Generic.Commenting.DocComment.ShortNotCapital
Description: Doc comment short description must start with a capital letter
/**
* this does something.
*/
/**
* This does something.
*/
Spacing After Doc Comment
Rule ID: Generic.Commenting.DocComment.SpacingAfter
Description: Additional blank lines found at end of doc comment
Number of Blank Lines Before Tags
Rule ID: Generic.Commenting.DocComment.SpacingBeforeTags
Description: There must be exactly one blank line before the tags in a doc comment
Number of Spaces Before Tag Value
Rule ID: Generic.Commenting.DocComment.TagValueIndent
Description: Tag value for @package tag indented incorrectly
Missing Doc Comment for Class
Rule ID: PEAR.Commenting.ClassComment.Missing
Description: Missing doc comment for class component
class Foo
{
}
/**
* Description of the Foo class.
*/
class Foo
{
}
Missing File Doc Comment
Rule ID: PEAR.Commenting.FileComment.Missing
Description: The file doc comment is missing from the start of the file
<?php
class Foo
{
}
<?php
/**
* Short description of this file.
*/
class Foo
{
}
Missing Category Tag
Rule ID: PEAR.Commenting.FileComment.MissingCategoryTag
Description: Missing @category tag in file comment
/**
* Short description.
*
* @package MyPackage
*/
/**
* Short description.
*
* @category MyCategory
* @package MyPackage
*/
Missing License Tag
Rule ID: PEAR.Commenting.FileComment.MissingLicenseTag
Description: Missing @license tag in file comment
/**
* Short description.
*
* @package MyPackage
*/
/**
* Short description.
*
* @package MyPackage
* @license http://example.com/license MIT
*/
Missing Link Tag
Rule ID: PEAR.Commenting.FileComment.MissingLinkTag
Description: Missing @link tag in file comment
/**
* Short description.
*
* @package MyPackage
*/
/**
* Short description.
*
* @package MyPackage
* @link http://example.com
*/
Missing PHP Version
Rule ID: PEAR.Commenting.FileComment.MissingVersion
Description: PHP version not specified
Bad Comment Format
Rule ID: PEAR.Commenting.FileComment.WrongStyle
Description: You must use "/**" style comments for a file comment
<?php
/*
* My file.
*/
<?php
/**
* My file.
*/
Extra Parameter Comment
Rule ID: PEAR.Commenting.FunctionComment.ExtraParamComment
Description: Superfluous parameter comment
/**
* Greets a user.
*
* @param string $name User name.
* @param int $age User age.
*/
function greet($name)
{
}
/**
* Greets a user.
*
* @param string $name User name.
*/
function greet($name)
{
}
Missing Doc Comment for Function
Rule ID: PEAR.Commenting.FunctionComment.Missing
Description: Missing doc comment for function component
function foo()
{
}
/**
* Does foo.
*
* @return void
*/
function foo()
{
}
Parameter Comment Not Found
Rule ID: PEAR.Commenting.FunctionComment.MissingParamComment
Description: Missing parameter comment
/**
* Greets a user.
*
* @param string $name
*/
function greet($name)
{
}
/**
* Greets a user.
*
* @param string $name User name.
*/
function greet($name)
{
}
Missing Parameter Doc
Rule ID: PEAR.Commenting.FunctionComment.MissingParamTag
Description: Doc comment for parameter missing
/**
* Greets a user.
*/
function greet($name)
{
return "Hi $name";
}
/**
* Greets a user.
*
* @param string $name User name.
*/
function greet($name)
{
return "Hi $name";
}
Missing Return Tag
Rule ID: PEAR.Commenting.FunctionComment.MissingReturn
Description: Missing @return tag in function comment
/**
* Adds two numbers.
*
* @param int $a First.
* @param int $b Second.
*/
function add($a, $b)
{
return $a + $b;
}
/**
* Adds two numbers.
*
* @param int $a First.
* @param int $b Second.
*
* @return int
*/
function add($a, $b)
{
return $a + $b;
}
Parameter Name Mismatch
Rule ID: PEAR.Commenting.FunctionComment.ParamNameNoMatch
Description: Doc comment for parameter does not match actual variable name
/**
* Greets a user.
*
* @param string $username User name.
*/
function greet($name)
{
}
/**
* Greets a user.
*
* @param string $name User name.
*/
function greet($name)
{
}
Wrong Spacing After Parameter Type
Rule ID: PEAR.Commenting.FunctionComment.SpacingAfterParamType
Description: Expected 1 spaces after parameter type
Wrong Style for Function Comment
Rule ID: PEAR.Commenting.FunctionComment.WrongStyle
Description: You must use "/**" style comments for a function comment
// Does foo.
function foo()
{
}
/**
* Does foo.
*
* @return void
*/
function foo()
{
}
Perl-style Comments
Rule ID: PEAR.Commenting.InlineComment.WrongStyle
Description: Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
# Increment the counter.
$counter++;
// Increment the counter.
$counter++;
Asterisk Indentation
Rule ID: Squiz.Commenting.DocCommentAlignment.SpaceBeforeStar
Description: Expected 5 space(s) before asterisk
Files
Line Exceeds Length
Rule ID: Generic.Files.LineLength.TooLong
Description: Line exceeds 85 characters;
Use Include
Rule ID: PEAR.Files.IncludingFile.UseInclude
Description: File is being conditionally included; use "include" instead
if ($debug === true) {
require 'debug.php';
}
if ($debug === true) {
include 'debug.php';
}
Use Include Once
Rule ID: PEAR.Files.IncludingFile.UseIncludeOnce
Description: File is being conditionally included; use "include_once" instead
if ($load === true) {
require_once 'config.php';
}
if ($load === true) {
include_once 'config.php';
}
White Space
No Indent Tabs
Rule ID: Generic.WhiteSpace.DisallowTabIndent.NonIndentTabsUsed
Description: Spaces must be used for alignment; tabs are not allowed
Disallow Tab Indent
Rule ID: Generic.WhiteSpace.DisallowTabIndent.TabsUsed
Description: Spaces must be used to indent lines; tabs are not allowed
if ($valid) {
return true;
}
if ($valid) {
return true;
}
Object Operator Indentation
Rule ID: PEAR.WhiteSpace.ObjectOperatorIndent.Incorrect
Description: Object operator not indented correctly
Closing Brace Indentation
Rule ID: PEAR.WhiteSpace.ScopeClosingBrace.Indent
Description: Closing brace indented incorrectly
Wrong Indentation
Rule ID: PEAR.WhiteSpace.ScopeIndent.Incorrect
Description: Line indented incorrectly
Wrong Exact Indentation
Rule ID: PEAR.WhiteSpace.ScopeIndent.IncorrectExact
Description: Line indented incorrectly
Functions
No Spaces After Comma
Rule ID: Generic.Functions.FunctionCallArgumentSpacing.NoSpaceAfterComma
Description: No space found after comma in argument list
$result = implode(',',$parts);
$result = implode(',', $parts);
Space Before Comma
Rule ID: Generic.Functions.FunctionCallArgumentSpacing.SpaceBeforeComma
Description: Space found before comma in argument list
foo($a , $b);
foo($a, $b);
Multi-line Function Closing Bracket
Rule ID: PEAR.Functions.FunctionCallSignature.CloseBracketLine
Description: Closing parenthesis of a multi-line function call must be on a line by itself
Multi-line Function Opening Bracket
Rule ID: PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket
Description: Opening parenthesis of a multi-line function call must be the last content on the line
Empty Lines Not Allowed
Rule ID: PEAR.Functions.FunctionCallSignature.EmptyLine
Description: Empty lines are not allowed in multi-line function calls
Multi-line Function Indentation
Rule ID: PEAR.Functions.FunctionCallSignature.Indent
Description: Multi-line function call not indented correctly
Opening Statement Indentation
Rule ID: PEAR.Functions.FunctionCallSignature.OpeningIndent
Description: Opening statement of multi-line function call not indented correctly
Space After Closing Bracket
Rule ID: PEAR.Functions.FunctionCallSignature.SpaceAfterCloseBracket
Description: Space after closing parenthesis of function call prohibited
Spaces After Opening Bracket
Rule ID: PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket
Description: Space after opening parenthesis of function call prohibited
Spaces Before Closing Bracket
Rule ID: PEAR.Functions.FunctionCallSignature.SpaceBeforeCloseBracket
Description: Expected 0 spaces before closing parenthesis
Brace On Same Line
Rule ID: PEAR.Functions.FunctionDeclaration.BraceOnSameLine
Description: Opening brace should be on a new line
function foo() {
}
function foo()
{
}
Close Bracket Line
Rule ID: PEAR.Functions.FunctionDeclaration.CloseBracketLine
Description: The closing parenthesis of a multi-line function declaration must be on a new line
No Content After Brace
Rule ID: PEAR.Functions.FunctionDeclaration.ContentAfterBrace
Description: Opening brace must be the last content on the line
function foo() { return true;
}
function foo()
{
return true;
}
New line Before Opening Brace
Rule ID: PEAR.Functions.FunctionDeclaration.NewlineBeforeOpenBrace
Description: The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Space After Function
Rule ID: PEAR.Functions.FunctionDeclaration.SpaceAfterFunction
Description: Expected 1 space after FUNCTION keyword
function foo()
{
return true;
}
function foo()
{
return true;
}
Space Before Brace
Rule ID: PEAR.Functions.FunctionDeclaration.SpaceBeforeBrace
Description: Expected 1 space before opening brace
function foo(){
return true;
}
function foo() {
return true;
}
Space Before Opening Parenthesis
Rule ID: PEAR.Functions.FunctionDeclaration.SpaceBeforeOpenParen
Description: Expected 0 spaces before opening parenthesis
function foo ()
{
return true;
}
function foo()
{
return true;
}
Naming Conventions
No Underscore Before Private Method Name
Rule ID: PEAR.NamingConventions.ValidFunctionName.PrivateNoUnderscore
Description: Private method name must be prefixed with an underscore
private function doThing()
{
}
private function _doThing()
{
}
Name Format
Rule ID: PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
Description: Public method name is not in camel caps format
class Foo
{
public function get_user_name()
{
}
}
class Foo
{
public function getUserName()
{
}
}
No Underscore Before Private Member Variable
Rule ID: PEAR.NamingConventions.ValidVariableName.PrivateNoUnderscore
Description: Private member variable must be prefixed with an underscore
class Foo
{
private $count;
}
class Foo
{
private $_count;
}
Control Structures
Inline Control Structures
Rule ID: Generic.ControlStructures.InlineControlStructure.Discouraged
Description: Inline control structures are discouraged
if ($valid === true)
doSomething();
if ($valid === true) {
doSomething();
}
Number of Spaces Before Opening Brace
Rule ID: PEAR.ControlStructures.MultiLineCondition.SpaceBeforeOpenBrace
Description: There must be a single space between the closing parenthesis and the opening brace of a multi-line IF statement
Spacing After Opening Brace
Rule ID: PEAR.ControlStructures.MultiLineCondition.SpacingAfterOpenBrace
Description: First condition of a multi-line IF statement must directly follow the opening parenthesis
Format
No PHP code found
Rule ID: Internal.NoCodeFound
Description: No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.
Minified File
Rule ID: Internal.Tokenizer.Exception
Description: File appears to be minified and cannot be processed
Security
Cyclopt scans your PHP code for security vulnerabilities, injection, insecure configuration, weak cryptography, data exposure, and more. Each finding below lists its Rule ID, what it detects and how to fix it, a severity, and the relevant CWE/OWASP classification.
Doctrine Dbal Dangerous Query
Rule ID: doctrine-dbal-dangerous-query
Description: Building a Doctrine DBAL statement from a non-literal $QUERY value passed to prepare, createQuery, or executeQuery can splice attacker-controlled SQL into the query. Bind the dynamic portion with placeholders and parameter arrays on the Connection instead of interpolating PHP variables into the SQL string.
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Doctrine Orm Dangerous Query
Rule ID: doctrine-orm-dangerous-query
Description: Non-literal expression spliced into a Doctrine ORM QueryBuilder call on $QUERY (for example via sprintf or "..." . $var). If the interpolated value originates from request input it produces an SQL injection. Bind values with setParameter() and reference them as placeholders (:name / ?) instead of concatenating them into the DQL fragment.
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Assert Use
Rule ID: assert-use
Description: Request data reaches assert() as a non-literal argument. When the assert.active ini setting is on (the legacy default), assert() treats string arguments as PHP code and evaluates them, which gives an attacker the same impact as eval(). Validate the value against a fixed allow-list or remove the dynamic assertion.
CWE: CWE-95 · OWASP: A03:2021, A05:2025
Assert Use Audit
Rule ID: assert-use-audit
Description: Passing a dynamic value to assert(...) is equivalent to invoking eval(...) on that value when assert.active and string-eval mode are enabled, so any attacker-controlled portion of $ASSERT becomes executable PHP. Rewrite the check as a plain boolean expression, or pass a closure to assert() so the argument is never re-parsed as code.
CWE: CWE-95 · OWASP: A03:2021, A05:2025
Backticks Use
Rule ID: backticks-use
Description: The PHP backtick operator silently hands its contents to shell_exec, so any interpolated variable inside `...` becomes part of the shell command line. Replace the backtick literal with a proc_open or escapeshellarg-wrapped call so untrusted input cannot break out into a separate command.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Base Convert Loses Precision
Rule ID: base-convert-loses-precision
Description: Feeding the output of random_bytes, openssl_random_pseudo_bytes, or a hash function into base_convert(...) collapses the value through a 64-bit integer internally, silently truncating entropy that the source produced. Session identifiers and CSRF tokens built this way become guessable. Encode the random bytes with bin2hex or sodium_bin2hex instead.
CWE: CWE-190
Curl SSL Verifypeer Off
Rule ID: curl-ssl-verifypeer-off
Description: curl_setopt(...) sets CURLOPT_SSL_VERIFYPEER to a falsy value ($IS_VERIFIED), which turns off TLS certificate validation on the cURL handle. Any attacker able to intercept the connection can present a self-signed certificate and read or alter the traffic. Leave the option at its default (true) and fix the local CA bundle if cURL is rejecting valid certificates.
CWE: CWE-319 · OWASP: A03:2017, A02:2021, A04:2025
Echoed Request
Rule ID: echoed-request
Description: Value from $_GET, $_POST or $_REQUEST reaches an echo statement without HTML escaping, which renders attacker-controlled markup or <script> payloads as part of the response (reflected XSS). Wrap the output in htmlspecialchars($value, ENT_QUOTES, 'UTF-8') (or the framework's equivalent helper) before emitting it.
CWE: CWE-79 · OWASP: A07:2017, A03:2021, A05:2025
Empty With Boolean Expression
Rule ID: empty-with-boolean-expression
Description: Wrapping a boolean expression like $A && $B directly inside empty(...) almost always reflects a misplaced parenthesis: empty is evaluated on the already-reduced boolean, not on the operands you likely intended to check. Move the closing paren so each variable is tested with its own empty call, or refactor the condition to a plain boolean check.
Eval Use
Rule ID: eval-use
Description: A call to eval(...) is being made with an argument that is not a fully literal string, meaning any portion derived from $_GET, $_POST, or other request data is parsed and executed as raw PHP. Refactor the code path to dispatch via a hard-coded map of callables or call_user_func against an allowlist instead of evaluating arbitrary source.
CWE: CWE-78 · OWASP: A01:2017, A03:2021, A05:2025
Exec Use
Rule ID: exec-use
Description: Process-launching APIs such as exec, passthru, proc_open, popen, shell_exec, system, and pcntl_exec are being invoked with a non-literal command string, so request-controlled values can inject extra shell tokens. Build the command from a fixed binary path plus an argument array, and run every dynamic fragment through escapeshellarg before concatenation.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Extract User Data
Rule ID: extract-user-data
Description: Passing $_GET, $_POST or $_FILES directly to extract() lets a request body declare arbitrary local variables in the current scope, silently overwriting things like $user or $isAdmin. If extract() is unavoidable, gate it with the EXTR_SKIP flag so existing variables are kept, or copy the few fields you actually need by name.
CWE: CWE-502 · OWASP: A08:2017, A08:2021, A08:2025
File Inclusion
Rule ID: file-inclusion
Description: A value flowing from $_GET, $_POST, $_COOKIE, $_REQUEST, or $_SERVER reaches an include, include_once, require, or require_once statement, enabling local or remote file inclusion that an attacker can pivot into arbitrary code execution. Resolve the requested module through a fixed switch over allowlisted filenames rather than embedding the request value directly.
CWE: CWE-98 · OWASP: A03:2021, A05:2025
FTP Use
Rule ID: ftp-use
Description: Any ftp_* helper (for example ftp_connect, ftp_login, ftp_get) negotiates a plaintext control and data channel, so credentials and file contents travel unencrypted across the network. Switch the transport to SFTP (ssh2_sftp) or FTPS via ftp_ssl_connect to obtain transport-layer protection.
CWE: CWE-319 · OWASP: A03:2017, A02:2021, A04:2025
LDAP Bind Without Password
Rule ID: ldap-bind-without-password
Description: Invoking ldap_bind($LDAP, $DN, NULL) or passing an empty string as the password performs an anonymous bind, so the resulting handle has no authenticated identity and can be used to query the directory without credentials. Supply a real password argument retrieved from secure configuration or fail closed when none is available.
CWE: CWE-287 · OWASP: A02:2017, A07:2021, A07:2025
Mb Ereg Replace Eval
Rule ID: mb-ereg-replace-eval
Description: The $OPTIONS argument of mb_ereg_replace(...) is non-literal, which means a request value containing the e modifier flips the function into eval mode and executes the replacement string as PHP. Hard-code the option flags or use mb_ereg_replace_callback so the replacement is never reinterpreted as source code.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Mcrypt Use
Rule ID: mcrypt-use
Description: Symbols from the mcrypt_* / mdecrypt_* family rely on libmcrypt, which has been unmaintained for years and was removed from PHP itself in 7.2. The available block modes default to insecure ECB-style behavior and lack authenticated encryption. Migrate to sodium_crypto_secretbox or the AEAD modes of openssl_encrypt.
CWE: CWE-676
MD5 Loose Equality
Rule ID: md5-loose-equality
Description: The result of md5(...), sha1(...), hash(...), or a related digest helper is being compared with ==/!=, which lets PHP type-juggle strings that start with 0e into floats and treat distinct "magic hash" values as equal. Replace the loose comparison with ===/!==, or use hash_equals for constant-time secret comparison.
CWE: CWE-697
MD5 Used As Password
Rule ID: md5-used-as-password
Description: The output of md5(...) (or hash('md5', ...)) is stored into a function whose name contains password. MD5 is fast, unsalted and has been broken for decades, so commodity GPUs recover the plaintext quickly; using it for credentials voids the protection a password hash is meant to provide. Switch to password_hash($plain, PASSWORD_BCRYPT) (or PASSWORD_ARGON2ID) and verify with password_verify().
CWE: CWE-327 · OWASP: A03:2017, A02:2021, A04:2025
Openssl Cbc Static Iv
Rule ID: openssl-cbc-static-iv
Description: openssl_encrypt/openssl_decrypt is called with a *-CBC cipher and a string-literal IV. Reusing the same IV across messages lets an attacker detect equal plaintext prefixes and run chosen-plaintext attacks against the ciphertext. Generate a fresh 16-byte IV per message with openssl_random_pseudo_bytes(16) and prepend it to the ciphertext so the receiver can read it back.
CWE: CWE-329 · OWASP: A02:2021, A04:2025
Openssl Decrypt Validate
Rule ID: openssl-decrypt-validate
Description: The return value of openssl_decrypt(...) is being assigned to $DECRYPTED_STRING without a subsequent strict comparison against false. When decryption fails (bad key, wrong cipher, tampered ciphertext) the function silently returns false, which downstream code typically treats as an empty string. Guard every call with if ($DECRYPTED_STRING === false) and fail closed.
CWE: CWE-252 · OWASP: A02:2021, A04:2025
Php Permissive CORS
Rule ID: php-permissive-cors
Description: A literal header("Access-Control-Allow-Origin: *", ...) is being emitted, which tells every browser that any external site may read the response. For endpoints that handle authenticated sessions this disables the Same-Origin Policy and exposes user data to cross-origin scripts. Echo back a specific origin validated against an allowlist instead of the wildcard.
CWE: CWE-346 · OWASP: A07:2021, A07:2025
Php SSRF
Rule ID: php-ssrf
Description: Request data from $_GET, $_POST, $_COOKIE, or $_REQUEST is being forwarded into $FUNCS (curl_init, curl_setopt, fopen, file_get_contents, or readfile) without restricting the destination, so the server can be coerced into fetching internal addresses such as the metadata endpoint. Resolve the host, reject private/loopback ranges, and only then perform the outbound request.
CWE: CWE-918 · OWASP: A10:2021, A01:2025
Phpinfo Use
Rule ID: phpinfo-use
Description: A phpinfo(...) call ships with the codebase. When reachable in production it dumps the loaded modules, environment variables, request superglobals, ini settings and absolute installation paths, which is everything an attacker needs to plan the next step. Remove the call or move it behind an authenticated, environment-gated diagnostics endpoint.
CWE: CWE-200 · OWASP: A01:2021, A01:2025
Printed Request
Rule ID: printed-request
Description: Output produced by print() here includes a value sourced from $_GET/$_POST/$_REQUEST with no HTML escaping applied, so any <script> or event-handler attribute supplied by the client will run in the victim's browser. Encode the value with htmlspecialchars() (or the framework's e()/esc_html() helper) before printing it.
CWE: CWE-79 · OWASP: A07:2017, A03:2021, A05:2025
Redirect To Request Uri
Rule ID: redirect-to-request-uri
Description: A Location: header is emitted with $_SERVER['REQUEST_URI'] appended verbatim. Browsers treat a value starting with // as a protocol-relative URL, so a request to /\/attacker.example sends the victim straight to attacker.example (open redirect). Build the redirect target from an internal allow-list or strip leading slashes before concatenating.
CWE: CWE-601 · OWASP: A05:2017, A01:2021, A01:2025
Sha224 Hash
Rule ID: sha224-hash
Description: Picking a 224-bit variant such as sha224, sha512/224, or sha3-224 inside hash() or hash_hmac() yields a digest length that several compliance baselines (NIST SP 800-131A, ASD ISM) no longer accept for new applications. Swap the algorithm string to sha384 or sha3-512 so the output meets the minimum security strength.
CWE: CWE-328 · OWASP: A03:2017, A02:2021, A04:2025
Tainted Callable
Rule ID: tainted-callable
Description: A request-controlled string is used as the callable argument of a higher-order function such as call_user_func, array_map or a callback setter. PHP will resolve any function or Class::method name the attacker supplies and invoke it, giving remote code execution. Dispatch through a fixed map of allowed handler names rather than passing user input through directly.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Tainted Exec
Rule ID: tainted-exec
Description: Shell-executing sink (exec, system, passthru, shell_exec, popen, proc_open with a string argv, or the backtick operator) receives a value tainted by $_GET/$_POST/$_COOKIE/$_REQUEST or php://input. Without escaping, an attacker can inject shell metacharacters and run arbitrary commands as the PHP user. Quote the argument with escapeshellarg() and, where possible, switch to the array form of proc_open so no shell is involved.
CWE: CWE-78 · OWASP: A03:2021, A05:2025
Tainted Exec
Rule ID: tainted-exec
Description: Command-execution sink ('exec', 'system', 'popen', 'passthru', 'shell_exec', 'pcntl_exec', 'proc_open') is invoked with a value that flows from '$_REQUEST'/'$_GET'/'$_POST'/'$_COOKIE'. Shell metacharacters such as ';', '|' or '' ' '' in the request let an attacker execute arbitrary commands as the PHP process. Pass each argument through 'escapeshellarg()' and prefer the array form of 'proc_open' so no shell is spawned.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Tainted Filename
Rule ID: tainted-filename
Description: Filesystem APIs such as fopen, file_get_contents, unlink or readfile receive a path built from $_GET/$_POST/$_COOKIE/ $_REQUEST/$_SERVER. The attacker can climb out of the intended directory with .. segments, target absolute paths, or supply a URL wrapper such as http:// or phar:// to trigger SSRF or deserialization. Resolve the path with realpath() and check that it sits inside an allow-listed directory before opening it.
CWE: CWE-918 · OWASP: A10:2021, A01:2025
Tainted Object Instantiation
Rule ID: tainted-object-instantiation
Description: The class name passed to new $SINK(...) is taken from a superglobal such as $_GET or $_POST. Because PHP autoloads and runs the matching constructor, an attacker can instantiate any class loadable by the application (including gadget chains used for deserialization-style attacks). Validate the requested class against a fixed allow-list before constructing it.
CWE: CWE-470 · OWASP: A03:2021, A05:2025
Tainted Session
Rule ID: tainted-session
Description: Assignment of the form $_SESSION[$KEY] = ... uses request data as the session-array key. Because session entries are normally server-trusted, letting the client pick the slot lets them overwrite authentication or authorization values such as $_SESSION['user_id'] or $_SESSION['is_admin'] (session poisoning). Restrict the key to a static literal or look it up in a fixed map.
CWE: CWE-284 · OWASP: A01:2021, A01:2025
Tainted SQL String
Rule ID: tainted-sql-string
Description: Hand-built SQL string (sprintf or "... $var ..." with a SELECT/INSERT/UPDATE/DELETE/CREATE/ALTER/DROP keyword) receives a value originating from $_GET/$_POST/$_COOKIE/ $_REQUEST, which exposes the database to SQL injection. Replace the concatenation with mysqli_prepare() (or PDO prepare()) plus bound parameters so the driver, not the string, handles user values.
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Tainted URL Host
Rule ID: tainted-url-host
Description: Request data is interpolated into the host portion of a URL string (the scheme:// segment) that is built with sprintf or string interpolation. An attacker can swap in their own domain to exfiltrate request data, or steer the call at an internal address such as 169.254.169.254 to read cloud metadata (SSRF). Take the host from configuration or check the candidate value against an allow-list of approved hostnames.
CWE: CWE-918 · OWASP: A10:2021, A01:2025
Unlink Use
Rule ID: unlink-use
Description: Passing a non-literal path to unlink(...) lets request-controlled traversal sequences such as ../../etc/... reach the filesystem, so an attacker can erase files outside the intended directory. Resolve the candidate path with realpath() and verify it lives under an expected base directory before deletion.
CWE: CWE-22 · OWASP: A05:2017, A01:2021, A01:2025
Unserialize Use
Rule ID: unserialize-use
Description: A dynamic value reaches unserialize(...), so any object whose class implements __wakeup, __destruct, or other magic methods inside the loaded autoload graph can be instantiated by the attacker, opening the door to PHP object-injection gadget chains. Encode the payload with json_encode/json_decode or pass an explicit allowed_classes list to lock down deserialization.
CWE: CWE-502 · OWASP: A08:2017, A08:2021, A08:2025
Weak Crypto
Rule ID: weak-crypto
Description: Functions like md5, sha1, md5_file, sha1_file, crypt, hash('md5', ...), and str_rot13 either rely on broken digest algorithms or provide no cryptographic protection at all, so values produced here cannot be relied on for integrity or password storage. Replace these with password_hash for credentials and hash('sha256', ...) (or stronger) for general-purpose digests.
CWE: CWE-328 · OWASP: A03:2017, A02:2021, A04:2025
Laravel Active Debug Code
Rule ID: laravel-active-debug-code
Description: Code is forcing APP_DEBUG=true via putenv, config(['app.debug' => 'true']), or $_ENV['APP_DEBUG'], which switches Laravel into Ignition/Whoops debug mode and dumps stack traces, environment variables, and database credentials on any uncaught exception. Drive APP_DEBUG exclusively from the .env file and keep it false outside of local development.
CWE: CWE-489 · OWASP: A05:2021, A02:2025
Laravel API Route SQL Injection
Rule ID: laravel-api-route-sql-injection
Description: The $METHOD handler for route $ROUTE_NAME forwards a closure argument straight into DB::raw(...) without using the bindings array. Any user-controlled fragment becomes raw SQL, producing injection. Call the overload DB::raw($expr, [...]) with parameter bindings, or build the query through Eloquent / the query builder instead of DB::raw.
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Laravel Blade Form Missing CSRF
Rule ID: laravel-blade-form-missing-csrf
Description: This Blade <form> posts a state-changing $METHOD request to $...ROUTE but the body is missing the @csrf directive, csrf_field(), or a csrf_token() hidden input, so Laravel's VerifyCsrfToken middleware will accept (or reject without context) cross-origin submissions. Insert @csrf immediately after the opening <form> tag so every mutating request carries the session token.
CWE: CWE-352 · OWASP: A01:2021, A01:2025
Laravel Cookie HTTP Only
Rule ID: laravel-cookie-http-only
Description: The Laravel config/session.php return array declares a cookie value but never pins http_only to true (or to an env(...) flag with that default), so the session cookie is readable from JavaScript and any XSS payload can steal it. Add 'http_only' => true to the session config so the browser blocks document.cookie access.
CWE: CWE-1004 · OWASP: A05:2021, A02:2025
Laravel Cookie Long Timeout
Rule ID: laravel-cookie-long-timeout
Description: The Laravel config/session.php 'lifetime' entry is hard-coded to more than 30 minutes, which extends the window in which a stolen session cookie remains valid. Cap the literal value to a short duration (or route it through env('SESSION_LIFETIME', 30)) so idle sessions expire promptly.
CWE: CWE-1004 · OWASP: A05:2021, A02:2025
Laravel Cookie Null Domain
Rule ID: laravel-cookie-null-domain
Description: The Laravel config/session.php array sets a cookie name but does not pin 'domain' => null (or an env(...) equivalent), so the cookie defaults to a broader domain scope that allows sibling subdomains to read it. Unless you genuinely run cross-subdomain auth, leave domain as null so the browser constrains the cookie to the issuing host.
CWE: CWE-200 · OWASP: A01:2021, A01:2025
Laravel Cookie Same Site
Rule ID: laravel-cookie-same-site
Description: The Laravel config/session.php return array configures a cookie but does not set 'same_site' to 'lax' or 'strict' (or to an env(...) flag with that default), so the browser will attach the session cookie to cross-site requests and enable CSRF. Add 'same_site' => 'lax' (or 'strict' for sensitive flows) to the session config.
CWE: CWE-1275 · OWASP: A01:2021, A01:2025
Laravel Cookie Secure Set
Rule ID: laravel-cookie-secure-set
Description: The Laravel config/session.php array sets a cookie but omits 'secure' => true (or an env(...) binding to that default), so the session cookie can be transmitted over plain HTTP and intercepted by a network attacker. Pin 'secure' => true so the browser only sends the cookie over TLS connections.
CWE: CWE-614 · OWASP: A05:2021, A02:2025
Laravel Dangerous Model Construction
Rule ID: laravel-dangerous-model-construction
Description: Declaring protected $guarded = []; on an Eloquent Model subclass turns off the blacklist entirely, so any request payload reaching Model::create($request->all()) can overwrite primary keys, role columns, or timestamps. Replace the empty guarded list with an explicit $fillable allowlist that names only the columns the form is allowed to set.
CWE: CWE-915 · OWASP: A08:2021, A08:2025
Laravel SQL Injection
Rule ID: laravel-sql-injection
Description: Eloquent builder method that interprets its argument as raw SQL (whereRaw, selectRaw, orderByRaw, DB::unprepared, ...) or as a dynamic column name (whereIn, pluck, orderBy, select, ...) receives a value sourced from $_GET/$_POST/$_COOKIE/ $_REQUEST/$_SERVER. The unescaped fragment makes the query open to SQL injection. Use the parameterised overload (e.g. whereRaw('col = ?', [$value])) or pass the user value as a regular where() binding rather than a column / raw expression.
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Laravel Unsafe Validator
Rule ID: laravel-unsafe-validator
Description: A Laravel Request field (or a FormRequest accessor such as $this->input, $this->query or $this->all) is handed straight to Rule::unique(...)->ignore(...). The ignore() argument is interpolated into the generated WHERE id != ... clause without quoting, so a crafted value produces SQL injection inside the validator. Cast the request value to an integer (or call ->ignore($model) with the actual model instance) before passing it to ignore().
CWE: CWE-89 · OWASP: A01:2017, A03:2021, A05:2025
Symfony CSRF Protection Disabled
Rule ID: symfony-csrf-protection-disabled
Description: A Symfony createForm, setDefaults, prependExtensionConfig, or loadFromExtension call is passing 'csrf_protection' => false, which disables the framework's hidden _token field and lets attackers submit forged form posts on behalf of authenticated users. Remove the override (or set it to true) so Symfony continues to validate the CSRF token on every submission.
CWE: CWE-352 · OWASP: A01:2021, A01:2025
Symfony Non Literal Redirect
Rule ID: symfony-non-literal-redirect
Description: A Symfony controller is calling $this->redirect(...) with a non-literal target, so a request parameter such as ?next=https://evil.example can steer the user-agent off the application's origin and into a phishing page. Pass a route name to $this->redirectToRoute(...) or validate the URL against an allowlist of trusted hosts before issuing the redirect.
CWE: CWE-601 · OWASP: A01:2021, A01:2025
Symfony Permissive CORS
Rule ID: symfony-permissive-cors
Description: Constructing a Symfony Response (or calling $RES->headers->set(...)) with Access-Control-Allow-Origin: * instructs every browser that any third-party origin may read this endpoint's body. For authenticated routes this voids the Same-Origin Policy and exposes user data to cross-origin scripts. Echo back a single origin validated against an allowlist instead of *.
CWE: CWE-346 · OWASP: A07:2021, A07:2025
Wp Ajax No Auth And Auth Hooks Audit
Rule ID: wp-ajax-no-auth-and-auth-hooks-audit
Description: Registering a custom AJAX endpoint through wp_ajax_* or wp_ajax_nopriv_* exposes a callback to authenticated users or unauthenticated visitors respectively. Audit the handler to ensure it enforces capability checks via current_user_can and validates nonces with check_ajax_referer before performing any state-changing action.
CWE: CWE-285 · OWASP: A01:2021, A01:2025
Wp Authorisation Checks Audit
Rule ID: wp-authorisation-checks-audit
Description: Authorization gates such as current_user_can, is_admin, is_user_logged_in, and is_user_admin were detected. Confirm that the correct capability is checked for the action being performed (for example manage_options for settings, edit_posts for content) and that the guard wraps every privileged branch rather than only a subset.
CWE: CWE-285 · OWASP: A01:2021, A01:2025
Wp Code Execution Audit
Rule ID: wp-code-execution-audit
Description: Dynamic PHP execution sinks such as eval, assert, and call_user_func were detected. When any portion of the evaluated string or callable name flows from $_GET, $_POST, or other request data, an attacker can achieve arbitrary code execution on the WordPress host. Replace these constructs with a fixed dispatch table or strictly whitelist the values that may reach the sink.
CWE: CWE-94 · OWASP: A03:2021, A05:2025
Wp Command Execution Audit
Rule ID: wp-command-execution-audit
Description: Process-spawning sinks system, exec, passthru, and shell_exec were found in the plugin. Concatenating any request value (for example from $_REQUEST or a register_rest_route callback argument) into the command string allows OS command injection. Build arguments through escapeshellarg/escapeshellcmd, or, preferably, invoke a fixed binary with a hard-coded argument list.
CWE: CWE-78 · OWASP: A03:2021, A05:2025
Wp CSRF Audit
Rule ID: wp-csrf-audit
Description: Invoking check_ajax_referer with false as the $die argument makes the function return a boolean instead of terminating the request when the nonce is missing or invalid. Unless the return value is explicitly inspected and the request aborted, the AJAX handler still executes and the CSRF protection is effectively bypassed. Omit the third argument or pass true so WordPress halts the request on failure.
CWE: CWE-352 · OWASP: A05:2021, A02:2025
Wp File Download Audit
Rule ID: wp-file-download-audit
Description: Arbitrary file-read primitives file, readfile, and file_get_contents were detected. If the path argument is influenced by request data, an attacker can traverse outside the plugin directory and exfiltrate secrets such as wp-config.php. Resolve the path with realpath, confirm it lives under an expected base directory, and enforce a capability check via current_user_can before serving the bytes.
CWE: CWE-73 · OWASP: A01:2021, A01:2025
Wp File Inclusion Audit
Rule ID: wp-file-inclusion-audit
Description: Statements include, require, include_once, require_once, and fread were detected. When the included path or filename is built from request data, this becomes a Local File Inclusion or, if allow_url_include is enabled, a Remote File Inclusion that leads to code execution. Restrict the includable set to a hard-coded whitelist and resolve the final path against the plugin's base directory.
CWE: CWE-22, CWE-73, CWE-98 · OWASP: A01:2021, A08:2021, A01:2025, A08:2025
Wp File Manipulation Audit
Rule ID: wp-file-manipulation-audit
Description: Deletion primitives unlink and wp_delete_file were detected. A request-controlled path argument enables an attacker to remove arbitrary files on the server, including .htaccess, plugin bootstrap files, or wp-config.php, which can take the site offline or, in some configurations, trigger the WordPress install screen. Validate that the target sits inside an expected uploads subdirectory and require the matching capability through current_user_can.
CWE: CWE-22, CWE-73, CWE-98 · OWASP: A01:2021, A08:2021, A01:2025, A08:2025
Wp Open Redirect Audit
Rule ID: wp-open-redirect-audit
Description: A call to wp_redirect was found. Unlike wp_safe_redirect, this function does not consult the allowed_redirect_hosts filter, so passing a request-controlled URL lets an attacker bounce visitors to a phishing or malware domain while the link still appears to originate from the trusted WordPress site. Swap the call for wp_safe_redirect or validate the destination against a fixed allow-list of hosts.
CWE: CWE-601 · OWASP: A05:2021, A02:2025
Wp Php Object Injection Audit
Rule ID: wp-php-object-injection-audit
Description: Deserialization sinks unserialize and maybe_unserialize were detected. Feeding attacker-controlled bytes to either function lets magic methods such as __wakeup or __destruct execute on reconstructed objects, which historically chains into RCE through gadgets present in WordPress core or popular plugins. Persist data in JSON form and rehydrate it with json_decode, reserving maybe_unserialize for trusted internal storage only.
CWE: CWE-502 · OWASP: A03:2021, A05:2025
Wp SQL Injection Audit
Rule ID: wp-sql-injection-audit
Description: Raw wpdb query methods (query, get_var, get_row, get_col, get_results, replace) were invoked without going through wpdb->prepare. Concatenating request data directly into the SQL string produces SQL injection that can leak wp_users hashes or escalate privileges. Build every dynamic query via $wpdb->prepare( $sql, $args ) using placeholders such as %s, %d, and %i, or use the higher-level insert/update/delete helpers.
CWE: CWE-89 · OWASP: A03:2021, A05:2025
Wp SSRF Audit
Rule ID: wp-ssrf-audit
Description: Outbound HTTP helpers such as wp_remote_get, wp_safe_remote_get, wp_safe_remote_request, wp_safe_remote_head, wp_safe_remote_post, wp_oembed_get, and vip_safe_wp_remote_get receive a URL that taints from $_GET, $_POST, $_REQUEST, get_option, get_user_meta, or get_query_var. An attacker can pivot the WordPress host into internal networks or the cloud metadata endpoint, yielding Server-Side Request Forgery. Restrict the URL to an allow-list of hosts and resolve the target IP to confirm it is not private or link-local before issuing the request.
CWE: CWE-918 · OWASP: A10:2021


