Composer version constraints like * or dev-master allow uncontrolled upgrades, introducing unexpected vulnerabilities. Strict, semantic versioning ensures dependencies are predictable and security patches are applied consistently. Avoiding wildcards prevents accidental installation of insecure or unstable releases.
Composer allows version constraints like * or x.* which match any version.
Using wildcards is dangerous because it removes control over which package version gets installed.
A new release (even with breaking changes or vulnerabilities) may be pulled in automatically without review,
leading to unexpected regressions or exposure to untested code.
Requiring explicit, pinned, or semver-safe ranges (^, ~) ensures only intended versions
are installed and security upgrades can be managed in a controlled way.
# Search for wildcard constraints in composer.json
grep -E "\"[0-9]+\.\*\"" composer.json
grep -E "\"\*\"" composer.json
# Expected: no wildcards present
# Bad
"vendor/extension": "*"
"vendor/extension": "2.*"
# Good
"vendor/extension": "^2.4.5"
"vendor/extension": "~2.4"
composer outdated to track available updates instead of relying on wildcards.# composer.json
"require": {
"vendor/extension": "*"
}
# Any future version (including insecure) could be installed → FAIL
# composer.json
"require": {
"vendor/extension": "^2.4.5"
}
# Safe range explicitly defined → PASS