
MachForm is a software package written in PHP, developed by APPNITRO SOFTWARE. It lets you host and create complex forms yourself, and manage user feedback via its administration interface.
During a web application penetration test, Vladimir TOUTAIN discovered two major vulnerabilities that could be exploited by an authenticated attacker on the backend with access to the entries of at least one form. They allow the execution of arbitrary SQL queries (SQL injections) in the database in order to read form data to which the attacker has no access, retrieve configuration information, and may allow arbitrary account theft. Versions of MachForm < v25 are affected with a patch deployed by the editor in v25.
Vulnerability details
The pentested application was running the latest version of MachForm to date (v24), so there were no known exploitable CVEs on this version. The auditor therefore focused on the configuration performed by the customer: account and form permissions, web server security hardening, MachForm configuration. Finding no flaws, he set about finding new vulnerabilities in the MachForm v24 solution – zero-days vulnerabilities that could be exploited.
Two authenticated SQL injections have been discovered, relating to the management of form entries: in the filtered CSV export, and in their filtered display.
1/ SQLi in filtered input export
The “entries_id” parameter sent to the server during an HTTP GET request to “export_entries.php” (filtered CSV export of form entries) is not filtered correctly and allows data stored in the database to be extracted: SQL commands are injected into the user input in order to affect the execution of predefined SQL commands.
This vulnerability can be exploited by an authenticated attacker with access to form entries using a UNION-based technique, enabling easy retrieval of data from the database. However, technical limitations make it difficult to exploit: the “,” character is changed to “‘,'” in the final request, which prevents the payload from being freely constructed. In addition, the size of the returned data is limited, which may necessitate building the exploit in several queries in order to extract large quantities of data. The exploit also varies according to the number of fields parameterized in the form.
/export_entries.php?type=csv&form_id=XXXXXX&csrf_token=TOKEN&entries_id=186,185185′)+UNION+SELECT+(select+database())’,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56′–+UgjQ&incomplete_entries=0&selected_fields=1
The answer to the “select database()” request will be found in the CSV export returned by the server.
It is then possible to extract valid sessions from other users, or force a password reset and then steal the reset_hash contained in the ap_users table. Note that even if LDAP authentication is enabled and the GUI doesn’t show the password reset option, a POST request to reset_password.php will be accepted and the reset_hash can be sent to reset.php encoded in base64 in the GET “q” parameter:
/reset.php?q=dXNlcl9pZD0xMzM3JnJlc2V0X2hhc2g9MzdjZWU5ZmExYTI2MjZhZWVmYWZkZWFkYmVlZg==
2/ SQLi in the input filter function
The “element_name” JSON field of the “filter_prop” object sent to the server during an HTTP POST request to “save_filter.php” (filtered display of form entries) is not properly secured and allows data stored in the database to be extracted: SQL commands are injected into the user input in order to affect the execution of predefined SQL commands. This injection is referred to as second-order, as the request to save_filter.php is used to save the filter, while the injection is actually executed when the input to the attacked form is displayed.
This vulnerability can be exploited by an authenticated attacker with access to form inputs. On the other hand, it is complex to exploit because the injection size is limited and there is no return of the result (BOOLEAN BLIND).
In order to use it with sqlmap, it is possible to use advanced options:
sqlmap -r actual_sqli –force-ssl –dbms=mysql –level 5 –risk 3 –second-req=second_order_request
In this sqlmap command we give the vulnerable HTTP request via the actual_sqli file and then the second HTTP request to be made to retrieve the result of the injection in the second_order_request file.
Contents of acutal_sqli :
Contents of second_order_request :
Exploiting this SQL injection is more complex and time-consuming, as it is of the blind type.
Communication with the software publisher
Appnitro Software’s contact form was used to ask how to securely inform them of any vulnerabilities discovered.
The response was very rapid, as was the qualification of the vulnerabilities and their correction.
2025/03/18: Contact form used
2025/03/18: Return of the founder of Appnitro Software and subsequent dispatch of vulnerability details
2025/03/20: Return from Appnitro Software confirming the vulnerabilities and indicating their correction in v25. Agreement on a disclosure schedule.
2025/03/29: MachForm v25 published https://www.machform.com/blog-machform-25-released/
2025/04/04: Publication of this article
🛡️ DSecBypass accompanies you on the security audits of your business applications. Do not hesitate to contact us for additional information and/or a personalized quote 📝.