burti/ass-xmlsecurity
burti/ass-xmlsecurity adds XML security helpers to Laravel, protecting against XXE and XML injection attacks by safely parsing and sanitizing untrusted XML input. A small utility package for apps that handle XML from external sources.
Pull the package in and check what it actually ships before writing any code:
composer require burti/ass-xmlsecurity
The repository is a thin XML Security library (XML DSig / XML Encryption), so the first thing to do is open vendor/burti/ass-xmlsecurity/src and identify the entry classes — typically a signature builder, a key/certificate object, and an encryption helper. If there is a Laravel service provider or facade it will be auto-discovered; if not, wire the library manually in a register()/singleton() binding rather than calling it from controllers.
Your first realistic use case with a Laravel app is signing an outbound XML document: a SAML AuthnRequest, a SOAP request for a government/finance endpoint, or a signed XML payload posted to a partner. Start with a throwaway tinker script:
DOMDocument.storage/app/keys (never from config/).saveXML().Get one signature verified end-to-end before you design the abstraction — the canonicalization details are where the whole integration lives or dies.
Wrap it in a single domain service. Create App\Services\XmlSigner (and XmlVerifier) that takes a DOMDocument or an XML string and returns signed/verified output. Bind it as a singleton in a service provider and inject it — this keeps library-specific classes out of your controllers and makes it trivial to swap the underlying implementation later.
Config, but not too much config. Put certificate paths, key paths, signature algorithm, and a clock_skew value in config/xmlsecurity.php, reading paths from env(). Resolve the actual key material lazily in the service, not at config-load time, so config:cache in production does not try to read a file.
Sign on the way out, verify on the way in. Two distinct patterns:
Http::withBody($xml, 'text/xml')->post(...). Avoid re-parsing/re-serializing between signing and sending.$request->getContent() (raw body, not $request->input()), rejects anything unsigned, then validates NotBefore/NotAfter with a skew tolerance.Keep key handling in one place. Load private keys from storage/app/keys or a secrets manager via a small KeyStore class; rotate by swapping the file, not by editing code. Log the certificate fingerprint (never the key) on each signature so you can trace which key was used in production.
Test with fixtures, not the network. Store a known-good signed XML fixture plus its certificate, and assert both verify() === true and that a tampered copy fails. Run this in CI — signature regressions are silent otherwise.
XXE and entity expansion. Always load with entity substitution disabled and network access blocked (libxml_disable_entity_loader on older PHP, or simply never pass LIBXML_NOENT and pass LIBXML_NONET). This is the single most common way an XML-signing integration becomes an attack surface.
Canonicalization mismatches. Inclusive vs exclusive C14N, whitespace, attribute ordering, and encoding will each break verification against a partner. If the other side rejects your signature, diff the canonicalized bytes, not the raw XML — the problem is almost always there, or in the signed-namespace/reference URI.
Namespaces and ID attributes. Reference URIs like #_abc123 only resolve if you correctly register the ID attribute type. Default namespaces on the signed element are a frequent cause of "reference not found."
Key and certificate formats. PEM vs DER, chain order, and base64 vs binary encoding differ by partner. Store both the key and cert explicitly; signing with a key whose cert doesn't match produces valid-looking output that fails at the other end.
Algorithm policy. Don't accept SHA-1 or RSA-SHA1 by default even if the library allows it; whitelist SHA-256+ and validate the declared algorithm on verification.
Clock skew. Partners' clocks drift. Add a small tolerance (e.g. 60–300s) around NotBefore/NotAfter instead of exact comparison.
Pin the version and watch upstream. This is a low-star fork; the XML Security space is a moving target. Note that it is a re-package, and track the upstream project (e.g. robrichards/xmlseclibs) for security fixes. Lock the version in composer.json and review changelogs before bumps.
Extension points. Because it's a small library, expect to subclass or wrap the signing/encryption classes to add your own algorithm constraints, logging, or custom key resolution — do that in your own app/ namespace, not by patching vendor/.
How can I help you explore Laravel packages today?