Payments are experiencing issues due to temporary restrictions in Russia. If your payment does not go through, please submit a support request.Our support team is available 24/7 — we are always here to help with hosting and server issues.We are now accepting requests for dedicated server rental and colocation services in our data center.Reminder: we recommend enabling backups for additional data protection.A new VPS/VDS lineup with NVMe storage and improved performance is now available.Maintenance work on some servers has been completed. All services are operating normally.
Logicloud: Health. Medical Institution Website

WEBSITE TEMPLATE

Logicloud (formerly Logicloud)

Logicloud: Health. Medical Institution Website

The Logicloud Health template is designed for creating websites for clinics, dental offices, and other medical facilities. The solution is based on experience gained from developing and launching projects in the medical sector. All essential sections are pre-configured, requiring only the addition of relevant content.

5.00/5 · 1 rating

1C-Bitrix Marketplace: 5/5 · 1 rating

Technical details

Published
16 August 2022
Updated
21 October 2026
Version
2.0.2
Installed
100–499 times
Compatible editions
Start, Standard, Small Business, Business
Responsive design
Yes
Composite support
No
Compatible with Sites24
No
Developer
Logicloud (formerly Logicloud)

What this solution does

The Logicloud Health template is designed for creating websites for clinics, dental offices, and other medical facilities. The solution is based on experience gained from developing and launching projects in the medical sector. All essential sections are pre-configured, requiring only the addition of relevant content.

The site includes a version for visually impaired users compliant with legal requirements and is fully adapted for smartphones and tablets. A convenient online booking form allows users to schedule appointments with specialists from any page. The template also features contact forms for user inquiries and a structured services section for clear information presentation.

The template allows creating a separate page for each doctor with detailed specialist information. Sections for 'Reviews' and 'Q&A' are included to collect patient feedback. The solution is built on standard 1C-Bitrix components, ensuring extensive possibilities for further customization.

When needed, General iT can implement “Logicloud: Health. Medical Institution Website”, configure the solution and continue developing the project after launch.

UPDATE HISTORY

What’s new

2 releases
2.0.2 (21.10.2026)Latest update

Version 2.0.2 — fix for a fatal module connection error

This update replaces a single file — include.php. Installation over versions 2.0.0 and 2.0.1 is mandatory.

What was fixed

Fatal error "syntax error, unexpected token opening angle bracket, expecting end of file" in include.php on the first line. The module did not connect at all: both the public part and the "Installed Solutions" page in the administrative section crashed.

Cause. When publishing to the Marketplace, include.php is wrapped with license protection: the file code is embedded in the middle of the wrapper, the opening tag is removed from it, and a check block starting with an opening tag is appended to the end. This block assumes that the file code closed the PHP tag itself. In versions 2.0.0 and 2.0.1, include.php was formatted in a modern style without a closing tag, so the opening tag of the check block ended up inside the PHP code.

Solution. include.php now ends with a closing tag as required by the wrapper. Additionally, the use operator and single-line comments have been removed from the file: the wrapper minifies the code into a single line, and in this form both constructs are unreliable — classes are specified by their full names. File formatting requirements are described in a comment inside the file to prevent them from being lost in future edits.

If the module is already installed and the admin panel is inaccessible

The "Installed Solutions" page connects the module during rendering, so before installing this update it will crash. Replace the file /bitrix/modules/logicloud.health/include.php with the correct version manually (via the hosting file manager or via FTP), replacing the entire file, not appending to it — after this the administrative section will open and the update can be installed in the usual way.

The module's composition and behavior do not change: only the file formatting was fixed. The registered classes remain the same — Main, Settings, Security\Captcha, Security\FormSigner, Iblock\Resolver.

2.0.0 (15.09.2026)

Version 2.0.0 — refactoring, security, Yandex SmartCaptcha and support for PHP 8.5

Attention. This version contains incompatible changes (see the "Incompatible Changes" section). Before updating a live site, create a backup.

1. Vulnerability fixes

Anonymous invocation of arbitrary core events (submit.php). The form endpoint executed GetModuleEvents("main", $_POST['EVENT_ID'], true) and ExecuteModuleEventEx($arEvent, array($_POST)) — any visitor could anonymously invoke any event handler of the main module with fully controllable arguments. Now the event name is taken only from the signed settings of the component, the handler search scope is limited to the logicloud.health module, and the handler receives a filtered set of fields based on a whitelist instead of the entire $_POST.

Unauthenticated writing to an arbitrary information block (mass assignment, submit.php). IBLOCK_ID, SECTION_ID, ACTIVE, IBLOCK_ITEM_NAME were accepted from the request, and all other keys from $_POST were placed into PROPERTY_VALUES. Server-side form parameter signing has been introduced (\Logicloud\Health\Security\FormSigner based on Bitrix\Main\Security\Sign\Signer): the browser returns a signed string that cannot be tampered with. The information block is additionally checked for ownership by the current site, properties are accepted only from the list of fields declared in the component settings, and only from the set of actually existing information block properties.

Captcha verification only on the client side. Previously, JS contacted ajax/captcha.php and, upon receiving "OK", sent the data to submit.php — the direct POST did not pass the captcha at all. Token verification has been moved to the server and is performed in the same request where the form data is processed (class \Logicloud\Health\Security\Captcha).

Unauthenticated file upload (submit.php). Files were accepted without restrictions and saved to the root /upload/. Now uploads are possible only in 'File' type fields declared in the component settings, an allowlist of extensions is enforced (jpg, jpeg, png, gif, webp, bmp, pdf, doc, docx, xls, xlsx, odt, ods, rtf, txt, csv, zip), a size limit of 10 MB is applied, is_uploaded_file() is checked; files are stored in a separate directory /upload/lcld.forms/ and are bound to the module.

Unauthenticated writing to an arbitrary information block (making-accept.php). IBLOCK_ID was taken from $_POST['iblockId']. The information block is now determined on the server by the symbolic code (lcld_online_form) within the current site, properties are accepted only from the list of properties of this information block, the doctor is checked for belonging to the doctors information block and for activity. The call to explode('-', $key)[1] without checking for the existence of the element, which caused a warning and path disclosure in logs, has been fixed.

Disclosure of other information blocks' data (making-form.php). Via $_POST['doctorId'], the name and image of any element of any information block could be retrieved. The selection is limited to the doctors information block and active elements, and handling for a missing element has been added.

Stored XSS in reviews (news.list/reviews and news.list/mainpage.reviews). The REVIEW and FIO properties were output without escaping, and the data source was a public form. The REVIEW value is passed through CBXSanitizer (SECURE_LEVEL_MIDDLE level), while FIO and the date are fully escaped.

CSRF on the module settings page (options.php). The $_REQUEST['LCLD_SETTINGS'] handler saved settings without checking sessid and without checking permissions. check_bitrix_sessid() and bitrix_sessid_post() have been added to the form, and a 'W' permission check for the module via $APPLICATION->GetGroupRight() has been added.

Removal of standard permission checks (options.php). The constant NOT_CHECK_PERMISSIONS = true is no longer declared — permission checks are now performed by the core, and the page additionally verifies permissions and sessid independently. The module has group rights enabled (MODULE_GROUP_RIGHTS).

CSRF protection on the settings page copy (/bitrix/admin/lcld_template_settings.php). Secured by the same checks — both pages now use a single implementation.

Insecure data deserialization during import (services/classes/chighloadblocks.php). Values with the prefix serialize# were passed to unserialize() without class restrictions (PHP Object Injection). The parameter allowed_classes = false has been added, along with handling for invalid values.

Insecure module settings deserialization. At all points (header.php, footer.php, captcha.php, settings pages, form template), calls to unserialize(Option::Get(...)) have been replaced with the class Logicloud Health Settings using allowed_classes = false, type checking, and a static cache.

Unescaped output of settings. Addresses, phone numbers, working hours, social media links, favicon, and logos in header.php and footer.php are now escaped; external links have rel="noopener noreferrer" added. The Third-party scripts field (scripts_text) continues to be output as HTML — this is its intended purpose — but it can now only be written by a user with the W permission for the module and only with a valid sessid.

Escaping in the form template and breadcrumbs. Headings, descriptions, placeholders, field values and codes, links, and navigation chain titles are output via htmlspecialcharsbx(); form settings are passed to JS via CUtil::PhpToJSObject().

2. Migration from Google reCAPTCHA v3 to Yandex SmartCaptcha

Form validation has been switched to Yandex SmartCaptcha. The token is verified on the server at the specified address; the result is read from the status field of the response (ok/failed).

Settings fields have been replaced: instead of 'Private Key', 'Public Key', and 'Minimum User Rating Value', there are now 'Client Key' and 'Server Key'. The rating threshold has been removed — SmartCaptcha provides a binary response, and it does not include a score value. The link to the console for obtaining keys now points to Yandex Cloud.

Keys are stored in the same module settings under the new names captcha_client_key and captcha_server_key. Inapplicable Google keys (captcha_public_key, captcha_private_key, captcha_value) are automatically removed from settings upon update.

The template connects the widget in render=onload mode. The captcha is invisible: the widget is rendered into a hidden form container and triggered upon submission; visitors only see the verification in disputed cases.

The intermediate request to ajax/captcha.php has been removed. This is not an optimization but a service requirement: the SmartCaptcha token is single-use and valid for five minutes, so a preliminary check would consume it, causing all subsequent form submissions to fail with an error. The token is sent immediately to ajax/submit.php along with the form data. The file ajax/captcha.php remains and returns a 410 code so that visitors with cached old script versions receive a clear response instead of a 404.

Widget errors (network-error, javascript-error) have been handled, and a timeout safeguard has been added: if a visitor closes the verification window, the form does not remain in a suspended state.

After successful submission and after an error, the widget is reset — resubmitting the form works without page reload.

Server responses with code 403 (including failed captcha) are shown to the visitor as a separate message, not as a generic 'server error'.

3. Audit results prior to publication (skills bitrix-tools/marketplace-security-skills)

The build was checked using the scan and journal-review skills from the bitrix-tools/marketplace-security-skills set. Medium-level vulnerabilities found during this check have been fixed in this same version.

Bypass of the catalog on the template settings page. The Bitrix\Main\UI\FileInput widget's tmp_name field was inserted into the path as-is: $_SERVER['DOCUMENT_ROOT'] . '/upload/tmp' . $fileData['tmp_name']. The value comes from a hidden form field, so a user with 'W' permission on the module could pass a tmp_name like '/../../bitrix/php_interface/dbconn.php' along with name='logo.png': CFile::SaveFile checks the extension based on the name field, but copies the file using the path from tmp_name. An arbitrary server file could end up in the web-accessible /upload/ directory and become accessible via a direct link, and due to the 'del' => 'Y' parameter, it was also deleted from its original location. Now the path is normalized via realpath() and accepted only if it remains within /upload/tmp and points to an existing file; additionally, a whitelist of extensions (jpg, jpeg, png, gif, webp, svg, ico) is enforced, and rejected files display a clear error message instead of being silently saved.

Stored XSS in reviews on the service detail page. The news.list/services.detail template output the REVIEW and FIO properties of related reviews without escaping, while a sanitizer was already applied in two other review templates. The data source is anonymous—reviews are created via a public form—so a visitor could inject a script that executed for all page readers and for the administrator when viewing the element. Review text now passes through CBXSanitizer (SECURE_LEVEL_MIDDLE), while FIO and date are fully escaped.

Reflected XSS in the header of internal pages. headerBufferedContent.php printed the concatenation of $APPLICATION->GetTitle() and page parameters (pageDescription, servicesDesc, minPrice, doctorPrice, doctorMeasure), while directly inserting the values of linkMaking, doctorImg, and doctorMakingLink into the href and src attributes. The GetTitle() method, unlike ShowTitle(), returns the title without HTML encoding, and the search template places the value of the q request parameter into the page title—a request such as /search/?q=ltimg src=x onerror=...gt executed script in the visitor's browser without any authorization. All values are escaped via htmlspecialcharsbx().

Permanent signature of form parameters. The signature prevented parameter substitution but lacked scope and expiration: once removed from the page, it remained valid indefinitely, and after changing component settings (e.g., setting ACTIVE='Y' to disable submission for moderation), the old configuration could still be used. The signed set now includes SITE_ID, FORM_ID, and a timestamp; ajax/submit.php accepts the signature only for the current site and only if it is no older than one day, with a 5-minute tolerance for clock drift; otherwise, it returns 403 SIGNATURE_EXPIRED.

Other audit findings involve outputting content from information blocks and component parameters without htmlspecialcharsbx in approximately thirty templates. The source of this data is the administrator or content editor, which is a trusted role in 1C-Bitrix; therefore, they are classified as template hardening and are excluded from this version.

4. Support for PHP 8.5

Short PHP opening tags have been removed from the template language files, in include/breadcrumb.php and in install/version.php; when short_open_tag is set to Off, the code was being output as text.

Constant redeclaration (NO_KEEP_STATISTIC, NOT_CHECK_PERMISSIONS) has been resolved — in PHP 8.5, redeclaring constants is deprecated; define() with a defined() check is now used.

Variables $by and $order passed by reference to CEventMessage::GetList(), CLanguage::GetList(), CSite::GetList() are now initialized (install/events.php, install/index.php, chighloadblocks.php, cfiles.php, ciblock.php) — previously 'Undefined variable' was issued.

Calls to strlen() and trim() with potential null values have been removed (wizard.php, cfiles.php) — passing null to string functions is deprecated as of PHP 8.1.

Installer class properties are now explicitly declared instead of using var and dynamic properties (deprecated as of PHP 8.2).

usort(..., strcmp($a["SORT"], $b["SORT"])) sorting has been replaced with numeric comparison using the less-than operator and a default value — strcmp(null, null) is deprecated, and lexicographical comparison of numbers produced incorrect ordering (10 before 2).

References to non-existent array keys in templates and result_modifier functions (?? and isset) and count() on potential null values have been fixed — in PHP 8 this caused a TypeError.

Calls to private methods of the CHighloadblocks class as global functions (__hlImportPrepareField, __getEnumUserFields) have been corrected — fatal error during HL-block import.

A check for the minimum PHP version with a clear message has been added to the installer.

Outdated branches with direct mysqli_* calls in services/classes/autoload.php have been replaced with the core API.

5. Caching errors

PAGE_DESCRIPTION was registered in SetResultCacheKeys() only for the root section (doctors.section, prices, news/prices/catalog.section). On all other pages, component_epilog.php read an unregistered key, causing the section description to disappear when cached, and a warning was added in PHP 8. The key is now registered unconditionally.

The same fix applies to SERV_DESC, MIN_PRICE, and LINK_MAKING in news.list/services.detail: LINK_MAKING now always goes into cache keys (previously it was set only when doctors were present).

In news/prices/section.php, the $sectionIds variable was not initialized: in the absence of subsections, endDataCache() received an undefined value, and after reading the cache, the data did not match the structure.

The price fetch cache (news/prices/section.php, news/prices/news.php) lived only by time and did not reset when content changed. A tag registration for the information block (iblock_id_N) was added via the managed cache — the fetch updates immediately after editing services and sections.

The cache lifetime was reduced from 36000000 seconds (more than 400 days) to reasonable values in all template components and in the custom price cache.

Fetching sections deeper than the second level was performed without an information block filter and collected sections from all information blocks on the site — IBLOCK_ID was added.

Values read from the cache are checked for type before use.

6. Bug fixes

The module's include.php file was empty — classes from the lib/ directory were never loaded. Autoload registration was added.

In the lib/ directory, there were two files differing only by case (Main.php and main.php) with different classes: on Windows and macOS, one would overwrite the other during distribution unpacking. One implementation was kept — lib/main.php, class \Logicloud\Health\Main.

When uninstalling the module, the settings page remained in /bitrix/admin: DeleteDirFiles() was called with a non-existent path install/admin instead of install/assets/admin.

news.list/services.detail: if a section was missing (incorrect PARENT_SECTION or inactive), the page crashed with the error «Call to a member function GetFields() on null». The same was fixed in news.list/documents, news.list/making.doctors, news.list/services.section.

news.list/services.detail: doctor sorting was applied to a non-existent key $sections[ID]['DOCTORS'] and effectively did not work.

news.list/services.detail: minimum price calculation considered zero and empty values and could return 0.

news.list/documents: accessing $sections[...] before its creation caused a warning «Undefined array key», and elements of non-existent sections were lost.

Installation wizard: the condition for selecting the default template was mutually exclusive and always reset the template to an empty string.

Installation Wizard: the content of css/style.css was read from the disk and inserted into the page within a loop over templates — as many times as templates were found. The style is read once and cached.

services/classes/autoload.php: the IsUtf8() method could return an undefined variable and did not recognize utf8mb4/utf8mb3 encodings.

Contact form: any non-empty response string was considered successful. Now an HTTP 200 status is additionally checked; the endpoint returns correct 403/405/413/415/500 codes.

Price list: third-level subcategories were selected by a separate query for each list item (N*M queries per page). The selection has been moved out of the loop.

news.list/services.detail: doctor data was selected one element per service (N+1 problem). Replaced with a single selection by ID list.

7. Refactoring

Added a module class layer with autoloading: \Logicloud\Health\Settings (reading and writing settings), \Logicloud\Health\Main (general utilities), \Logicloud\Health\Security\FormSigner (form parameter signing), \Logicloud\Health\Security\Captcha (server-side reCAPTCHA verification), \Logicloud\Health\Iblock\Resolver (searching information blocks by code and property whitelist).

The template settings page existed as two diverging copies of 390 lines each (options.php and install/assets/admin/lcld_template_settings.php). The implementation has been moved to admin/settings_page.php, and both entry points have been reduced to thin wrappers.

The global function array_filter_recursive() has been replaced by the \Logicloud\Health\Main::filterRecursive() method; the old function remains as a wrapper for backward compatibility and is protected against redeclaration.

The logicloud.health:forms component has been rewritten: duplication during field parameter parsing has been removed, default values have been added, escaping has been implemented, and a unified error message mapping has been created.

Modal form template: two almost identical JS initialization blocks have been merged into one; settings are passed via CUtil::PhpToJSObject() instead of manual JSON assembly.

callback.js: two nearly verbatim duplicate blocks for displaying form errors have been merged into the _showErrors() method; CAPTCHA handling has been moved to _getCaptchaToken() using promises.

include/breadcrumb.php has been rewritten with readable markup including schema.org microdata for all elements of the chain, including the current page.

Dead and commented-out code has been removed; indentation, quotes, and type declarations in the affected files have been unified; comments have been added to explain non-trivial solutions.

8. Incompatible changes

The form user event (parameter "Use user event") is now searched among handlers registered for the logicloud.health module, not main. Existing handlers must be re-registered: AddEventHandler('logicloud.health', 'YOUR_EVENT', ...).

The event handler receives an array containing only the fields declared in the component settings, instead of the entire $_POST.

The public endpoint ajax/submit.php accepts only requests with a correct parameter signature. Direct calls from third-party code that manually constructed POST requests will no longer work.

After the update, the form is protected by CAPTCHA only when SmartCaptcha keys are filled. Google keys are not migrated (they are not applicable) and are removed from the settings. Obtain client and server keys in Yandex Cloud SmartCaptcha and specify them in the module settings — until then, the forms work without CAPTCHA.

The ajax/captcha.php endpoint no longer performs verification and responds with code 410. If you called it from your code, remove this call.

The form parameter signature is valid for one day and only for the site where it was issued. If the page with the form is served from a long-lived cache (composite cache, CDN), ensure that the cache lifetime is less than one day, otherwise the visitor will receive a 403 SIGNATURE_EXPIRED response.

The module settings page requires the 'W' permission for the logicloud.health module. After the update, check the permissions of user groups.

Changes to the website template (catalog install/wizards/.../site/templates/logicloud.health) are copied to /bitrix/wizards and applied by the wizard during installation. For an already deployed website, the corresponding template files must be transferred manually, taking your modifications into account.

USER EXPERIENCE

Solution reviews

How does this solution work in a real project? Share your experience and help others choose.

Be the first to share your experience

There are no reviews of this solution on git.ru yet. Tell us what worked well and what could be improved.

Verified purchaseAdd a key if you wish. A verified review gets a badge, priority placement and more rating weight.

Open to every clientJust sign in to your account. A key is optional; all reviews are moderated.

YOUR EXPERIENCE MATTERS

Your review

YOUR PROJECT INFRASTRUCTURE

A home for your website

BEFORE YOU ORDER

Let’s go through the details.

What does the price cover?
The displayed price covers the solution itself. Platform licensing, installation and customisation are checked separately. If the page offers bundles, select the required option before submitting a request.
How do I check compatibility?
Compare the supported editions and solution version in the technical details with your project. Before installing on a live website, we recommend making a backup and checking the solution in a test environment.
Is there a trial?
The developer lists a trial of 20 days. The trial button opens the installer in your website control panel. Check the required features and compatibility before purchasing.
How much does this solution’s renewal cost?
The current renewal price is 17,450 ₽. Before you order, a manager will confirm the renewal period and whether it applies to your licence.
Can you help with implementation?
We can help launch a website using the selected template, agreeing on its structure, content migration and integrations. The schedule and cost depend on the project and are quoted separately.

GENERAL iT

Let’s discuss your project

Получатель: ООО «Дженерал Ай Ти Рус»

1C-BITRIX

Install solution

Enter a domain with or without https://. The installer will open in your website control panel in a new tab.

Solution screenshots

Solution screenshot