When you install a PHP library, Composer checks version numbers. It does not check licenses. If you think an MIT tag in composer.json makes your whole app safe for business use, you are trusting a label that Composer never checks against real dependencies.
Composer does not check license compatibility
When an author puts a library on Packagist, they write a license name in composer.json. Packagist stores that text and shows it on the web page. Composer reads it when you run composer licenses.
Neither tool checks whether that license works with other packages in your tree. If an MIT package needs a GPL or OSL library, Composer still installs it without warnings. The problem stays hidden until someone audits the full tree.
The PayPal SDK: how OSL-3.0 reached online stores
When PayPal retired older PHP SDKs, they told merchants to use paypal/paypal-server-sdk. On Packagist, PayPal listed this package as MIT.
Looking at the real dependency tree shows a different setup:
paypal/paypal-server-sdk (Packagist says MIT | Archive contains PayPal EULA)
\-- apimatic/core (Declared MIT | Upstream notices stripped)
\-- apimatic/jsonmapper (SPDX: OSL-3.0 - Open Software License 3.0)
\-- forked from cweiske/jsonmapper (Copyright Christian Weiske & Netresearch)
The issue is OSL-3.0 Section 5 ("External Deployment"). Standard GPL only triggers when you share files. OSL-3.0 treats web access as distribution:
If you run an online store or SaaS app with OSL-3.0 code, users can ask for your source code. PayPal built their SDK with APIMatic tools. APIMatic used an OSL-3.0 tool from Christian Weiske. Any store using PayPal's new SDK pulled OSL-3.0 into their stack.
WPForms Lite: renaming classes does not change copyright
WordPress.org requires all hosted plugins to use GPLv2 or later compatible terms. To stop class name clashes, plugin authors often use tools like PHP-Scoper to add prefixes to third-party code.
In our scan of WPForms Lite (Rank #9 on WordPress.org, 5,000,000+ active installs), the plugin placed the APIMatic SDK in:
wp-content/plugins/wpforms-lite/vendor_prefixed/apimatic/jsonmapper/
This changed class names to WPForms\Vendor\apimatic\jsonmapper\JsonMapper, but kept the file comments. Five PHP files in that folder still hold the full Open Software License 3.0 text and copyright notices.
Prefix tools change PHP code names. They do not change license rights. Putting OSL-3.0 files inside a GPLv2 plugin creates an unresolved conflict across millions of WordPress sites.
Five libraries behind most copyleft findings
Most of the 320 flagged packages came from five upstream projects:
ezyang/htmlpurifier(LGPL-2.1-or-later, 108 packages): Used by frameworks likeyiisoft/yii2and tools likemews/purifier. Loading an untouched library via Composer matches LGPL dynamic linking rules, but authors often forget to include the LGPL license file and notices.netresearch/jsonmapper/apimatic/jsonmapper(OSL-3.0, 27 packages): Used in code tools, JSON-RPC servers (danog/advanced-json-rpc), and Psalm plugins.enshrined/svg-sanitize(GPL-2.0-or-later, 26 packages): Used by CMS plugins and shop add-ons that claim MIT terms. GPL-2.0 has no linking exception, so putting it in closed-source code creates a direct conflict.paragonie/haliteandhidden-string(MPL-2.0, 24 packages): Cryptography libraries. MPL-2.0 works at the file level, so you can use it in commercial apps if edits to MPL files stay open and notices stay in place.dompdf/dompdfandsmalot/pdfparser(LGPL-2.1 / LGPL-3.0, 20+ packages): PDF tools used in invoice makers (likehorstoeko/zugferd) and Laravel wrappers (barryvdh/laravel-dompdf).
Check your vendor folder right now
You can check your dependencies from the command line:
# 1. List all licenses found in your lockfile
composer licenses --format=json
# 2. Search vendor files for copyleft headers
grep -rEi "General Public License|Open Software License|Mozilla Public License" vendor/ \
--include="*.php" --include="*LICENSE*" --include="*NOTICE*" | head -n 30
# 3. Find why a package was installed
composer why apimatic/jsonmapper
composer why ezyang/htmlpurifier
composer why enshrined/svg-sanitize
AI agent rule: check licenses before adding code
AI coding tools often pick packages based on popularity or root tags. Give your AI agents this rule so they check lockfiles before adding new packages:
Full data and tools
The full dataset of 10,000 packages, edge tables, WordPress logs, and scripts are open in the StackHal repository under docs/research/composer-license-audit/.
Sources and links: Composer Lock Documentation | OSI Open Software License 3.0 | WordPress.org Plugin Guidelines | StackHal Research Dataset