...

NDV Product Image Upload for WooCommerce

Complete Documentation & User Guide

Free v1.1.0 · Pro add-on v1.1.0

🔍 No matching content found

Try searching with different keywords

Plugin Overview

NDV Product Image Upload for WooCommerce lets your customers — including guests, with no account required — upload and crop custom images and PDFs on a product page before adding the product to the cart. Every rule is set per product: how many files are required, the maximum file size, which formats are allowed, minimum and maximum image resolution, the crop shape and aspect ratio, and the upload button’s text and colour.

The free plugin is published on WordPress.org and is fully functional on its own. A separate Pro add-on extends it with bulk operations, settings import, a security-log dashboard and an Elementor widget. Throughout this documentation, anything that needs the Pro add-on is marked (Pro).

Perfect For:

  • Print-on-demand stores (custom t-shirts, mugs, posters)
  • Photography services (photo printing, canvas prints)
  • Design agencies (client artwork upload)
  • Custom manufacturing (personalized products)
  • Any business requiring customer-provided images

What's New in Version 1.1.0

Free plugin 1.1.0

  • Lock quantity to 1: a new per-product (and default) setting that stops customers ordering more than one of a product they upload custom artwork for. It is enforced through WooCommerce’s own woocommerce_is_sold_individually filter, so it never overrides a product you have already marked “Sold individually”.
  • WooCommerce 10.9 compatibility: confirmed with a full core-flow regression pass; the WC tested up to header was raised from 9.5.

Pro add-on 1.1.0

  • Rebranded to “NDV Product Image Upload — Pro” to match the renamed free base plugin.
  • Fixed: the Requires Plugins header still referenced the base plugin’s pre-rebrand slug, which made WordPress 6.5+ report the dependency as missing and block activation.
  • Fixed: the Pro admin script and the unlicensed-license notice were both gated on the base plugin’s old admin screen ID, so neither loaded on the settings page.
  • Security: settings import now sanitizes every section through the base plugin’s own validation before writing anything, instead of storing the uploaded file’s contents directly.
  • Fixed: importing a file whose product configurations were all unusable could overwrite your existing configurations with nothing and still report success. Such a file is now rejected and your settings are left untouched.
  • Improved: import now reports which section of a file is malformed, and tells you when configurations were dropped instead of showing an unqualified success message.

Core Features

Image Upload & Processing

Multi-Product Configuration

User Interface & Experience

WooCommerce Integration

Secure File Handling

Monitoring & Housekeeping

Installation Guide

Installing the free plugin

Before you install: WooCommerce must be installed and active — the plugin will not run without it. The minimum supported versions are WordPress 5.9, PHP 7.2 and WooCommerce 3.5. The Pro add-on additionally requires the free plugin to be installed and active; installing Pro on its own does nothing.

Configuration

Initial Setup Process

Step 1: Access Plugin Settings

After activation, go to NDV Image Upload in your WordPress admin sidebar. The settings screen opens on Default Settings. With the free plugin alone you get five tabs; the Pro add-on adds three more, for eight in total:

  • Global Settings – site-wide options
  • Default Settings – the starting values used when you create a new product configuration
  • Add Configuration – per-product setup
  • Bulk Operations – apply settings to many products at once (Pro)
  • Existing Configurations – review and edit what you have configured
  • Import/Export – restore settings from a JSON file (Pro)
  • Security Logs – upload audit dashboard (Pro)
  • Uninstall Preferences – choose whether to keep or delete your data

The three Pro tabs only appear on a licensed site.

Step 2: Configure Default Settings

Start on the Default Settings tab and set the values you expect to use most often. Getting these right first saves time, because they pre-fill the form every time you add a new product configuration.

Two things worth knowing:

  • Changing Default Settings does not alter products you have already configured — each configuration keeps its own saved values.
  • Default Settings do not switch uploads on anywhere by themselves. A product only offers uploads once you give it its own configuration on the Add Configuration tab.

Default Settings and their out-of-the-box values

  • Number of files: 1 to 50, default 9. This is an exact count — the customer must upload precisely this many files before they can add the product to the cart, not “up to” this many.
  • Maximum file size: default 5 MB per file. The minimum you can set is 1 KB; there is no plugin-imposed upper limit, so your server’s upload_max_filesize and post_max_size are the real ceiling.
  • Allowed file types: JPG, JPEG, PNG, GIF and WebP are enabled by default. PDF is supported but off by default — tick it to accept PDFs.
  • Button text: default Upload Files.
  • Button colour: default #4CAF50. It also tints the progress bar and the cropper.
  • Shape cropping: on by default — shows the None / Square / Rectangle / Circle / Heart selector in the crop modal.
  • Cropping ratio: default Free. Other choices are 1:1, 4:3, 16:9 and 2:3.
  • Resolution validation: off by default. Switch it on to enforce minimum and maximum pixel dimensions (each between 0 and 10000; 0 means “no limit”).
  • Lock quantity to 1: off by default.

Step 3: Set Up Products

Use the Add Configuration tab to give an individual product its own rules:

  1. Pick the product from the searchable dropdown (variations can be configured individually).
  2. Set the exact number of files required — images and PDFs count together toward the total.
  3. Set the maximum size per file.
  4. Choose the allowed file types, including PDF if you want it.
  5. Optionally turn on resolution validation and set the pixel bounds.
  6. Choose whether the shape selector is available, and set a fixed cropping ratio if you need one.
  7. Optionally tick Lock quantity to 1.
  8. Customise the button text and colour, then save.

With the Pro add-on you can do all of the above for many products at once on the Bulk Operations tab.

Important: the upload interface appears on a product only when that product has its own saved configuration and that configuration is enabled. A product you have never added on the Add Configuration tab shows no upload interface at all, whatever your Default Settings say. The one exception is the button text and colour: if you leave those blank on a product, the values from Default Settings are used instead. External and affiliate products are not supported.

Admin Interface Guide

Global Settings tab

Site-wide options that apply to every product with uploads enabled.

Default Settings tab

The starting values used whenever you create a new product configuration. They do not enable uploads anywhere on their own.

Add Configuration tab

Give an individual product — or an individual variation — its own upload rules.

Existing Configurations tab

Review, edit and remove everything you have configured so far.

Uninstall Preferences tab

Decide what happens to your data if the plugin is ever removed.

Bulk Operations, Import/Export and Security Logs (Pro)

Three additional tabs supplied by the Pro add-on. They appear only when Pro is installed and licensed.

Security Features

File Validation

Upload Security

Access Control

Monitoring & Logging (Pro)

Security Best Practices:

Usage Guide

For Store Administrators

Daily Management Tasks

  1. Review orders: uploaded files appear on the WooCommerce order screen, each with a preview and a download link. PDFs show a document icon.
  2. Manage configurations: add, edit or remove product configurations as your catalogue changes.
  3. Watch disk usage: uploaded files live in wp-content/uploads/custom_product_images/ and are deliberately kept out of the media library, so they will not appear in your Media screen.
  4. Check the Security Logs (Pro): look for repeated failed attempts, which usually indicate either a misconfigured file-type list or someone probing the endpoint.

Advanced Management

For Customers (Frontend Experience)

Upload Process

  1. Visit the product page: any product you have configured, whether the customer is logged in or shopping as a guest.
  2. Open the uploader: clicking the upload button opens a modal that states exactly what is required — how many files, which formats, the size limit and any resolution bounds.
  3. Choose files: images and PDFs can be selected together in one go.
  4. Crop if needed: click a thumbnail to open the cropper. PDFs are not cropped.
  5. Pick a shape: where the shape selector is enabled, choose None, Square, Rectangle, Circle or Heart. Circle and Heart are saved as transparent PNGs; everything else is saved as JPEG.
  6. Adjust: zoom, rotate in 90° steps, flip horizontally or vertically, or reset. Save the crop, or restore the original.
  7. Finish: click Done. The exact number of files required by that product must be present before the upload completes.
  8. Add to cart: the product goes into the cart with the files attached, and thumbnails appear alongside it.

Customer Benefits:

System Requirements

Server Requirements

Compatibility. The plugin is designed to work with any properly coded WordPress theme, and has been used with Twenty Twenty-One, Twenty Twenty-Two, Twenty Twenty-Three and Storefront. It supports both the classic WooCommerce cart and checkout and the newer WooCommerce Blocks cart and checkout, and is compatible with High-Performance Order Storage (HPOS).

Two limitations worth noting: external and affiliate products are not supported, and no server-side image processing is performed — the plugin does not resize, compress, watermark or convert uploads, and does not add them to the media library.

Development & Customization

WordPress Hooks & Filters

The free plugin exposes 8 filters and 5 actions. This is the same surface the Pro add-on is built on, and it is treated as stable public API — names and signatures are not changed without a major release, because live shops and the add-on both depend on them.

Everything is prefixed cpiu_. That prefix predates the plugin’s rename and is permanent: options, order-item meta, hooks and nonces all key off it.

Action Hooks

// Render extra fields on the Global Settings screen.
do_action( 'cpiu_global_settings_fields', $global_settings );

// Render extra fields on the per-product configuration form.
// $args['context'] is 'add' or 'edit' (and 'bulk' when Pro is active).
// In the 'add' context, $args['defaults'] also holds the Default Settings array.
do_action( 'cpiu_config_form_fields', $args );

// Fires after each file is stored successfully (3 call sites).
do_action( 'cpiu_file_uploaded', $upload_result, $product_id, $user_id );

// Fires on EVERY upload attempt, success or failure - the audit hook.
// $log_entry keys: timestamp, user_id, ip_address, product_id,
//                  status, success, filename, error_message
do_action( 'cpiu_upload_attempt', $log_entry );

// Daily cron event. Two core callbacks are already attached.
do_action( 'cpiu_cleanup_guest_uploads' );

Example — log every failed upload to your error log:

add_action( 'cpiu_upload_attempt', function ( $entry ) {
    if ( empty( $entry['success'] ) ) {
        error_log( sprintf(
            'CPIU upload failed for product %d: %s',
            $entry['product_id'],
            $entry['error_message']
        ) );
    }
} );

The free plugin fires cpiu_upload_attempt but stores nothing. The Pro add-on hooks it to build the Security Logs dashboard; you can hook it yourself instead.

Filter Hooks

// Register an additional admin tab.
// $tabs is a map of slug => array( label, icon, callback ).
apply_filters( 'cpiu_admin_tabs', $tabs );

// Extend or adjust global settings as they are saved.
apply_filters( 'cpiu_save_global_settings', $sanitized, $raw );

// Attach your own keys to a per-product configuration during sanitisation.
apply_filters( 'cpiu_sanitize_configuration', $sanitized, $config );

// Override the resolved configuration for a product on the front end.
apply_filters( 'cpiu_product_config', $config, $product_id );

// Return false to suppress the default front-end preview.
apply_filters( 'cpiu_show_image_preview', true, $product_id, $config );

// Extend the upload allowlists.
apply_filters( 'cpiu_allowed_mime_types', $default_mime_types );
apply_filters( 'cpiu_allowed_extensions', $default_extensions );

// Adjust how the client IP is resolved (proxies, CDNs).
apply_filters( 'cpiu_client_ip', $ip );

Example — add your own admin tab:

add_filter( 'cpiu_admin_tabs', function ( $tabs ) {
    $tabs['my-reports'] = array(
        'label'    => __( 'Reports', 'my-plugin' ),
        'icon'     => 'dashicons-chart-bar',
        'callback' => 'my_plugin_render_reports_tab', // receives array $context
    );
    return $tabs;
} );

Example — store your own key alongside each product configuration:

add_filter( 'cpiu_sanitize_configuration', function ( $sanitized, $raw ) {
    $sanitized['my_key'] = isset( $raw['my_key'] )
        ? sanitize_text_field( $raw['my_key'] )
        : '';
    return $sanitized;
}, 10, 2 );

⚠ Security note: cpiu_allowed_mime_types and cpiu_allowed_extensions control what the upload validator will accept. Widening them — adding SVG, for instance — bypasses a deliberate restriction and is a security decision, not a convenience tweak.

CSS Customization

The front-end markup uses stable, prefixed class names you can target from your theme’s stylesheet:

.cpiu-container              /* wrapper around the whole upload area */
.cpiu-upload-button-container
.cpiu-upload-btn             /* the upload button itself */
.cpiu-image-preview-section  /* "Your Uploaded files" panel */
.cpiu-no-images-message      /* empty state */
.cpiu-image-item
.cpiu-image-wrapper
.cpiu-delete-btn
.cpiu-modal                  /* upload modal */
.cpiu-modal-content
.cpiu-close-btn
.cpiu-done-btn
.cpiu-crop-hint
.cpiu-progress-wrapper
.cpiu-spinner
.cpiu-cart-thumbnails        /* cart */
.cpiu-cart-image-container
.cpiu-order-item-images      /* customer order view and emails */
.cpiu-order-image-container
.cpiu-admin-order-item-images/* admin order screen */

The button and progress-bar colours are driven by the per-product button colour setting, so change that in the admin rather than overriding it in CSS.

Registered asset handles, if you need to dequeue or depend on them: cpiu-frontend-multi-product, cpiu-cropper, cpiu-admin-multi-product, cpiu-admin-notices.

JavaScript

The plugin does not emit custom DOM events, and there is no documented JavaScript event API — if you have seen cpiu:upload:start or similar listed elsewhere, those events do not exist and never fired. Integrate through the PHP hooks above.

Two globals are available on a product page for reference:

// Localised configuration for the current product.
cpiu_params            // nonce, product_id, ajax_url, and the resolved config

// The cropper, exposed as a promise-based helper.
window.CPIUCropper.open( /* ... */ ).then( function ( result ) { /* ... */ } );

Uploads are posted as multipart/form-data to the cpiu_upload_mixed_files AJAX action, with images and PDFs sent together in a single request as native binary blobs.

Important: always extend through these hooks rather than editing plugin files directly, so your work survives updates. If you need something the current hooks cannot reach, ask us — the right answer is usually a new hook added to the free plugin, which then becomes available to everyone.

Troubleshooting Guide

Common Issues & Solutions

Upload button not appearing on product pages

Possible causes:

  • The product has no configuration on the Add Configuration tab. Default Settings alone do not switch uploads on anywhere.
  • The configuration exists but is disabled.
  • You configured the parent product, but the variation being viewed has its own disabled configuration.
  • The product is an external or affiliate product — these are not supported.
  • WooCommerce is not active.
  • Your theme overrides the single-product template and drops the woocommerce_after_add_to_cart_button hook the interface attaches to.
  • The Elementor widget is active and deliberately suppressing the default interface (Pro).

Solutions:

  1. Confirm the product is listed on Existing Configurations and is enabled.
  2. For a variable product, check the specific variation as well as the parent.
  3. Switch temporarily to a default theme such as Twenty Twenty-Four to rule out a template override.
  4. Open the browser console and look for JavaScript errors.
  5. Deactivate other plugins one at a time to find a conflict.
  6. If you use the Elementor widget, make sure it is placed on the template you are actually viewing (Pro).

Common causes:

  • The format is not enabled for that product — PDF is supported but switched off by default.
  • The file is larger than the product’s configured maximum, or larger than the server’s upload_max_filesize / post_max_size.
  • The wrong number of files was chosen. The count must match the product’s requirement exactly — it is not an upper limit.
  • The image falls outside the configured minimum or maximum resolution.
  • The file is not really the type its extension claims; the MIME sniff and image-signature checks reject it.
  • The filename contains a second, dangerous extension such as .php or .svg.
  • A guest attempted two uploads within a few seconds and hit the short cooldown.

Solutions:

  1. Check which formats are ticked for that product. Supported types are JPG, JPEG, PNG, GIF, WebP and PDF — PDF must be enabled explicitly.
  2. Compare the file size against both the plugin’s limit and your server’s PHP limits.
  3. Upload exactly the number of files the product asks for; images and PDFs count together toward that total.
  4. If resolution validation is on, check the image against the configured pixel bounds.
  5. Re-save the image from an image editor to rule out a corrupt or mislabelled file.
  6. Review the Security Logs for the precise error message recorded against the attempt (Pro).
  7. If nothing else explains it, ask your host whether a server-level rule such as ModSecurity is blocking the request.

Troubleshooting steps:

  1. Confirm the file is present in wp-content/uploads/custom_product_images/.
  2. Remember that files are served only through a tokenised URL. Opening the file’s direct path returns 403 by design — that is not the fault.
  3. On Nginx, add the deny rule shown in the FAQ; the bundled .htaccess is ignored there.
  4. Clear caching-plugin and CDN caches, and make sure the cart and checkout pages are excluded from page caching.
  5. Check that the uploads directory is readable by WordPress.
  6. If order-image auto-cleanup is enabled, check whether the retention period for that order has already elapsed — the files will have been deleted.

Possible solutions:

  1. Clear the browser cache and reload.
  2. Check the console. The cropper is built on Cropper.js v2, which uses custom elements — it will not run in Internet Explorer or in very old browsers.
  3. Deactivate other plugins one at a time to isolate a JavaScript conflict.
  4. Confirm the plugin’s asset files are readable and are not being blocked or mangled by a minification plugin.
  5. Note that PDFs are not croppable by design — clicking a PDF thumbnail will not open the cropper.
  6. If shape cropping is switched off for that product, no shape selector appears; only the configured aspect ratio is applied.

Performance Optimization

Debug mode: set WP_DEBUG and WP_DEBUG_LOG to true in wp-config.php to capture detailed errors in wp-content/debug.log. When reporting a problem to us, that log plus the exact error shown to the customer is by far the most useful thing you can send.

Frequently Asked Questions

How many files can customers upload per product?

Between 1 and 50 files, set per product. The default is 9.

One thing to be clear about: this is an exact count, not an upper limit. If a product is set to 3 files, the customer must supply exactly three before they can add it to the cart — not one, not five. Images and PDFs count together toward that total, so a product set to 3 can take two images and one PDF.

JPG, JPEG, PNG, GIF, WebP and PDF.

PDF is supported but switched off by default — enable it in Default Settings or on the individual product. You can allow any combination of the six types per product.

Every upload is checked three ways: the extension must be on the allowlist, the sniffed MIME type must match, and images must pass a signature check. Renaming a file to .jpg will not get it through. SVG is deliberately not supported, because SVG can carry executable script.

Yes. Every product — and every individual variation — can have its own rules: the number of files required, the maximum size per file, which formats are allowed, minimum and maximum image resolution, whether the shape selector is offered, a fixed cropping ratio, the button text and colour, and whether the quantity is locked to 1.

Products you have not configured show no upload interface at all. With the Pro add-on you can apply a set of rules to many products in one pass on the Bulk Operations tab.

Uploaded files are stored in wp-content/uploads/custom_product_images/, outside the media library, with randomised filenames and non-executable permissions. Each file is validated by extension, sniffed MIME type, image signature, a double-extension scan and a scan for executable content before it is stored. The directory gets a deny-all .htaccess, and files are only ever served through a tokenised endpoint that verifies an HMAC of the filename.

Recording those attempts is a Pro feature: the free plugin fires an audit action on every attempt but stores nothing, while the Pro add-on’s Security Logs tab keeps the most recent 1000 entries with success and failure counts.

On Nginx, .htaccess files are ignored entirely, so the bundled protection does nothing. Add this to your server block:

location ^~ /wp-content/uploads/custom_product_images/ {
    deny all;
    return 403;
}

Legitimate access still works, because the plugin serves files through its own tokenised endpoint rather than by direct path.

Yes to both. The plugin is compatible with WooCommerce High-Performance Order Storage (HPOS), including the order-image cleanup routine.

It also supports both checkout styles: the classic WooCommerce cart and checkout, and the newer WooCommerce Blocks cart and checkout. Uploaded files are attached to the order and shown to the customer either way.

Partly with the free plugin, fully with Pro.

The free plugin includes a one-way Export Settings Backup button on the Uninstall Preferences tab, which downloads your global settings, default settings and all product configurations as a JSON file. Taking that backup before a big change is a good habit.

Importing that file back — to restore it, or to copy a configuration to another site — requires the Pro add-on’s Import/Export tab. Pro re-validates every section through the free plugin’s own sanitiser before writing anything, and rejects a file whose product configurations are all unusable rather than silently overwriting your settings with nothing.

It works with any properly coded WordPress theme, and has been used with Twenty Twenty-One, Twenty Twenty-Two, Twenty Twenty-Three and Storefront. The interface picks up your theme’s styling, and the button colour is yours to set.

The one thing to watch for is a theme that replaces WooCommerce’s single-product template and drops the woocommerce_after_add_to_cart_button hook — the upload interface attaches there. If the button does not appear, test with a default theme to confirm that is the cause. With the Pro add-on you can sidestep the issue entirely by placing the Elementor widget wherever you want it.

You choose. The Uninstall Preferences tab offers two options: keep all data (the default, and the right choice for a temporary deactivation) or delete all plugin data on uninstall.

Files that are still referenced by an order are preserved either way, so removing the plugin will not strip artwork from orders you have yet to fulfil. Export your settings first if there is any chance you will reinstall.

Note that the upload folder name, custom_product_images, is fixed and will not change between releases — URLs already stored against your orders and already sent in order emails depend on it.

Version History & Changelog

Free plugin — 1.1.0 (current)

What changed

  • Added: Lock quantity to 1. A per-product (and default) setting that stops customers ordering more than one of a product they upload custom artwork for. It is enforced through WooCommerce’s own woocommerce_is_sold_individually filter, so it never overrides a product you have already marked “Sold individually”.
  • Compatibility: confirmed working against WooCommerce 10.9 with a full core-flow regression pass. The WC tested up to header was raised from 9.5.

Earlier releases & the Pro add-on

Free plugin — 1.0.0 · initial WordPress.org release

  • Per-product image and PDF upload with a built-in cropper — shapes, aspect ratios, zoom, rotate and flip.
  • Guest and logged-in uploads with secure, validated file handling.
  • Resolution validation, Default Settings, and global controls covering express-checkout hiding and order-image auto-cleanup.
  • HPOS compatibility and uninstall data preferences.

Pro add-on — 1.1.0 (current)

  • Rebranded to “NDV Product Image Upload — Pro” to match the renamed free base plugin.
  • Fixed: the Requires Plugins header still referenced the base plugin’s pre-rebrand slug, which caused WordPress 6.5+ to report the dependency as missing and block activation.
  • Fixed: the Pro admin script was gated on the base plugin’s old admin screen ID, so it never loaded on the settings page.
  • Fixed: the unlicensed-licence notice was gated on the same stale screen ID and never appeared where it should have.
  • Fixed: the licensing menu pointed at an admin page that no longer exists.
  • Security: settings import now sanitises every section through the base plugin’s own validation before writing anything, instead of storing the uploaded file’s contents directly.
  • Fixed: importing a file whose product configurations were all unusable could overwrite your existing configurations with nothing and still report success. Such a file is now rejected and your settings are left untouched.
  • Improved: import now reports which section of a file is malformed, and tells you when configurations were dropped instead of showing an unqualified success message.
  • Changed: per-upload pricing was removed from the feature list — the feature is not yet functional.
  • Note: the plugin folder, file name and text domain are unchanged in this release, so existing licences and automatic updates are unaffected.

Pro add-on — 1.0.0

  • Initial release, adding Bulk Operations, Import/Export, the Security Logs dashboard and the Elementor widget to the free base plugin.

Checking your installed version

Open Plugins in your WordPress admin. The free plugin is listed as NDV Product Image Upload for WooCommerce and the add-on as NDV Product Image Upload — Pro; each shows its version number beneath the name. Both are currently at 1.1.0.

The free plugin updates through WordPress.org like any other directory plugin. The Pro add-on updates through your licence.

In Development

Not yet available:

Support & Resources

📚 Documentation

This page is the complete setup guide and technical reference for both the free plugin and the Pro add-on.

💬 Professional Support

Direct help from our team with installation, configuration and troubleshooting. Pro customers are supported by email; free-plugin users are welcome to email us too, and can also use the WordPress.org support forum.

🌐 Company Website

Learn more about our products, services, and latest updates.
Visit Nowdigiverse⟶

🛡️ Security Issues

Report security vulnerabilities through responsible disclosure.
Report Security Issue⟶

Support Guidelines

Before Contacting Support:

  1. Check this documentation for solutions
  2. Review the FAQ section
  3. Try the troubleshooting steps
  4. Test with default WordPress theme
  5. Disable other plugins temporarily

When Contacting Support, Please Include:

📧 Contact Information

  • Support Email: hello@nowdigiverse.com
  • Website: https://nowdigiverse.com/
  • Response Time: Within 24-48 hours (business days)

Community & Contributions

We welcome feedback and contributions from the WordPress community. The free plugin is published on WordPress.org, follows WordPress coding standards, and exposes a documented hook surface so developers can extend it without editing plugin files.

Contributing: feature requests and general feedback are welcome through our support channels or the WordPress.org support forum. If you need a hook that does not exist yet, tell us — we would rather add it to the free plugin, where everyone benefits, than have you patch the plugin locally.

Security reports: please report suspected vulnerabilities privately by email rather than in a public forum, and give us a reasonable window to ship a fix before disclosing.

Let's discuss your project

We are committed to understanding your requirements and crafting a tailored solution that aligns with your goals.

Enter your details and someone from our team will reach out to find a time to connect with you.

Talk to a Specialist

Seraphinite AcceleratorOptimized by Seraphinite Accelerator
Turns on site high speed to be attractive for people and search engines.