Easy!Appointments 1.3.2 allows Sensitive Information Disclosure (Username and Password Hash)

1. Introduction

According to software owner’s website, Easy!Appointments, designed and developed by Alex Tselegidis, is an “open source appointment scheduler” and  “a highly customizable web application that allows your customers to book appointments with you via the web”. The software is also available as a WordPress Plugin.

In version 1.3.2 (which its vulnerability is found by the author, other versions have not been tested yet), there is a vulnerability in the booking process that exposes username and password hash of a service provider at the “confirmation” step.

The vulnerability was found during the penetration test phase when implementing the software in the author’s environment to ensure security.

Please note that there is a chance that the vulnerability will present in any older versions of the software.

2. Vulnerability Description

Sensitive information, which are username and password hash along with its salt of a service provider, exposure in the confirmation step of booking process as a JavaScript variable in Easy!Appointment version 1.3.2 allows an attacker to remotely access to such information via web browser and can ultimately crack the password.

3. Impact

The author successfully reverse-engineered the hashing process (this is relatively easy since the software is open source) and, provided with complete knowledge about password hash and salt, cracking the hash is highly feasible as demonstrated in section 5. Steps to reproduce the attack.

The password can then be used to gain access to backend management page which further exposes and violates other sensitive and private information including customers’ Personally Identifiable Information (PII) which is a serious concern all over the globe now.

4. Summary of Attack Vector

– Go to the booking page of Easy!Appointment application.

– Make an appointment as usual.

– Confirm the appointment by clicking “Confirm” button.

– At the final step, where the application confirms that the appointment has been registered and the email has been sent to you, view the source of the page. The username and password hash along with salt will be in a JavaScript object named “GlobalVariables”. Alternatively, we can use a non-transparent proxy to intercept the HTTP response after clicking the “Confirm” button to view the same information, whichever method suits your ego complex most.

5. Steps to Reproduce The Attack

To ensure unbiased result and that the vulnerability does not exist due to the author doing, we will also provide steps we took to get the application ready.

5.1 Prepare the environment

1.) Follow the installation guide as described at (last accessed on 8th September 2019).

2.) Access to the application for the first time will require us to fill in an administrative account before starting an installation process, so we filled in the information and click “Install Easy!Appointment”, as shown in figure 1 and 2.

Figure 1 Filled in the administrative account info.
Figure 2 Click “Install Easy!Appointment” at the bottom of the page.

3.) After a successful installation, the application will redirect us to the backend system of the application as shown in figure 3.

Figure 3 The application will be redirected here after a successful installation.

4.) We created a provider name “Doctor 1” with password “P@ssw0rd” as shown in figure 4, then we logged out of the backend system and proceed to book an appointment, as shown in figure 5.

Figure 4 Created a user “Doctor 1” with password ‘P@ssw0rd’, just for the demo sake.
Figure 5 Logged out and proceeded to book an appointment.

5.2 Vulnerability Discovery

1.) Proceed to make an appointment as guided by the application’s user interface.

2.) At the confirmation step, as shown in figure 6, before clicking “Confirm”, we configured our web browser to point to a non-transparent proxy, we used OWASP ZAP (no advertising intended). At this point the author assume that readers have already possessed the knowledge of using non-transparent proxy, if you have not, research.

3.) Instruct the proxy to intercept the connection.

Figure 6 Shows the confirmation step.

4.) After clicking “Confirm”, every request and response will be intercepted, look for the request to “/index.php/appointments/book_success/”, as shown in figure 7, and its associated response. We will see that username and password hash along with salt will be assigned to a JavaScript object named “GlobalVariables” in the message body, as shown in figure 8.

Figure 7 A vulnerable request.
Figure 8 A response with username, password hash and salt along with other information.

5.3 Cracking the salted hash

The routine used to produce hash is in “general_helper.php”. To summarize, salt hex string is split in to 2 equal halves, put a password string between those 2 halves will produce a salted password string  then hash the salted password string 100,001 times with SHA256 algorithm and you will get the password hash, to be technically specific, the salted password hash, the PHP code of the routine is shown in figure 9.

The practice of using salt with multiple rounds of hashing should be sufficient to secure the hash from being cracked, given that there is no access to source code and salt, but the exposure of the salted password hash and the salt itself have rendered the protection mechanism almost useless. Since the hash algorithm in use can be easily determined as shown in figure 10. Sure, there will be some guesswork and hash round brute forcing that still have to be done, but the chance of a successful cracking increased significantly.

Figure 9 The routine used to generate salted password hash.
Figure 10 Determine hash type using hashid

5.4 Password cracker Proof of Concept code

The author created a PoC code used to crack salted password hash, the code was written in Python and can be found at

Figure 11  Sample usage of password cracking code.

6. Remediation

The author has been attempting to contact the software developer but still has not received any response yet. So, here are things we can do to mitigate the impact

  • Use a very strong password, obviously.
  • As a quick fix, you can comment out the entire section that describes JavaScript object GlobalVariables located in book_success.php at line 68 (approximately).
  • Using Web Application Firewall, either software or hardware, free or commercial, whichever suits your situation, to filter the response containing sensitive information.
  • Waiting for an updated version from software vendor.

7. Contributors

  • Dr. Nipon Nachin (Peer Reviewer)
  • Sunt-tanarit Prapassaraporn (Author, Researcher)
  • Watchara Jungmongkolsawat (Researcher)
  • Natchaphon Burapanonte (Researcher)
  • Jaturong Lengho (Researcher)

8. References

  • Sunt-tanarit P., 2019, CVE-2019-14936, Black Dragon Cybersecurity Counselor, viewed 10 September 2019, <>.
  • Alex T., 2019, Easy Appointment Scheduling With Easy!Appointments,, viewed 10 September 2019, <>