
Research
6 Malicious Packagist Themes Ship Trojanized jQuery and FUNNULL Redirect Payloads
Six malicious Packagist packages posing as OphimCMS themes contain trojanized jQuery that exfiltrates URLs, injects ads, and loads FUNNULL-linked redirects.
form-attribution
Advanced tools
Automatically capture and persist marketing attribution data in your web forms.
A lightweight, zero-dependency script that automatically captures and passes the referrer, UTM parameters, ad click IDs, and more to your forms as hidden fields.
Try the Script Builder | View Documentation
window.FormAttribution for custom integrationsAdd the script to your website before the closing </body>tag:
<script src="https://cdn.jsdelivr.net/npm/form-attribution@latest/dist/script.min.js"></script>
That's it! The script will automatically:
| Parameter | Description |
|---|---|
utm_source | Traffic source (e.g., google, newsletter) |
utm_medium | Marketing medium (e.g., cpc, email) |
utm_campaign | Campaign name |
utm_term | Paid search keywords |
utm_content | Content variant for A/B testing |
utm_id | Campaign ID |
ref | Referrer tracking parameter |
| Parameter | Description |
|---|---|
landing_page | First page URL visited |
current_page | Current page URL (where form was submitted) |
referrer_url | Document referrer |
first_touch_timestamp | ISO 8601 timestamp of first visit |
data-click-ids="true")| Parameter | Platform |
|---|---|
gclid | Google Ads |
fbclid | Meta Ads |
msclkid | Microsoft Advertising |
ttclid | TikTok Ads |
li_fat_id | LinkedIn Ads |
twclid | Twitter/X Ads |
Configure the script by adding optional data attributes to the script tag:
<script src="/dist/script.min.js"
data-storage="localStorage"
data-field-prefix="attr_"
data-extra-params="gclid,fbclid"
data-exclude-forms=".no-track"
data-debug="true">
</script>
| Attribute | Default | Description |
|---|---|---|
data-storage | sessionStorage | Storage method: sessionStorage, localStorage, or cookie |
data-field-prefix | "" | Prefix for hidden field names (e.g., attr_ creates attr_utm_source) |
data-extra-params | "" | Comma-separated list of additional URL parameters to capture |
data-exclude-forms | "" | CSS selector for forms to exclude from injection |
data-storage-key | form_attribution_data | Custom key name for stored data |
data-debug | false | Enable console logging and debug panel |
data-privacy | true | Set to "false" to disable GPC/DNT privacy signal detection |
data-click-ids | false | Set to "true" to automatically capture ad platform click IDs |
When using data-storage="cookie":
| Attribute | Default | Description |
|---|---|---|
data-cookie-domain | "" | Cookie domain (e.g., .example.com) |
data-cookie-path | / | Cookie path |
data-cookie-expires | 30 | Expiration in days |
data-cookie-samesite | lax | SameSite policy: lax, strict, or none |
<script src="/dist/script.min.js"
data-storage="localStorage">
</script>
<script src="/dist/script.min.js"
data-storage="cookie"
data-cookie-domain=".example.com"
data-cookie-expires="90">
</script>
<script src="/dist/script.min.js"
data-exclude-forms=".login-form, [data-no-attribution]">
</script>
<script src="/dist/script.min.js"
data-field-prefix="lead_">
</script>
Use the interactive Script Builder tool to generate a configured script tag with a visual interface.
The script uses intelligent fallbacks when a storage type isn't available:
| Requested | Fallback Chain |
|---|---|
localStorage | localStorage → sessionStorage → cookie → memory |
sessionStorage | sessionStorage → cookie → memory |
cookie | cookie → memory |
By default, the script respects user privacy preferences:
navigator.globalPrivacyControl is trueWhen privacy signals are detected, no data is captured or stored. You can override this behavior by setting data-privacy="false" on the script tag.
Form Attribution exposes a global FormAttribution object for programmatic access:
// Get all attribution data
const data = FormAttribution.getData();
// Get a specific parameter
const source = FormAttribution.getParam('utm_source');
// Get tracked forms with their status
const forms = FormAttribution.getForms();
// Clear all stored data
FormAttribution.clear();
// Re-inject data into forms
FormAttribution.refresh();
// Register event callbacks (supports multiple listeners)
FormAttribution.on('onReady', ({ data, config }) => {
console.log('Attribution ready:', data);
});
// Remove a callback
FormAttribution.off('onCapture', myHandler);
| Method | Returns | Description |
|---|---|---|
getData() | Object|null | Get all captured attribution data |
getParam(name) | string|null | Get a specific parameter value |
getForms() | Array | Get list of forms with their status |
clear() | void | Clear all stored attribution data |
refresh() | void | Re-inject data into all forms |
on(event, cb) | Object | Register event callback (chainable) |
off(event, cb) | Object | Unregister a callback (chainable) |
| Event | Payload | Description |
|---|---|---|
onReady | { data, config } | Fired when initialization is complete |
onCapture | { data } | Fired when new data is captured |
onUpdate | { data } | Fired when data is updated |
Enable the debug panel by adding data-debug="true" to the script tag:
<script src="/dist/script.min.js" data-debug="true"></script>
The debug panel provides:
The panel is draggable, collapsible, and its state persists across page reloads. Uses Shadow DOM for style isolation.
Note: Remove
data-debugbefore deploying to production.
Hidden fields are injected with the following attributes:
<input type="hidden"
name="utm_source"
value="google"
data-form-attribution="true"
data-form-attribution-managed="true">
pnpm install
pnpm test # Run Playwright tests (Chromium, Firefox, WebKit)
pnpm exec playwright test --ui # Run tests with interactive UI
pnpm check # Lint with Biome
pnpm fix # Auto-fix lint issues
Built on standard browser APIs with graceful fallbacks for broad compatibility:
document.cookie for olderComplete documentation is available at https://form-attribution.flashbrew.digital/docs.
Built by Ben Sabic at Flash Brew Digital | GitHub
FAQs
Automatically capture and persist marketing attribution data in your web forms.
The npm package form-attribution receives a total of 4 weekly downloads. As such, form-attribution popularity was classified as not popular.
We found that form-attribution demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Six malicious Packagist packages posing as OphimCMS themes contain trojanized jQuery that exfiltrates URLs, injects ads, and loads FUNNULL-linked redirects.

Security News
The GCVE initiative operated by CIRCL has officially opened its publishing ecosystem, letting organizations issue and share vulnerability identifiers without routing through a central authority.

Security News
The project is retiring its odd/even release model in favor of a simpler annual cadence where every major version becomes LTS.