What Is OWASP — And Why Should Your Practice Care?

The Open Worldwide Application Security Project (OWASP) is a non-profit that maintains the most widely referenced list of web application vulnerabilities in the world. The OWASP Top 10 — last updated in 2021 — represents the ten most critical categories of risk affecting web apps, ranked by incidence, exploitability, and impact. Security teams and developers globally use it as their baseline for testing and hardening.

Here's the thing: when most doctors and dentists think about cybersecurity, they think about their local network — their NAS, their Carestream box, their Windows workstations. The WiFi in the waiting room. That's all real and important. But your web-facing attack surface is just as dangerous, and it's reachable by anyone on the planet without needing to be anywhere near Sandton or Bryanston or wherever your practice is.

Your online booking system. Your patient portal. Your practice management software that has a web interface. Your billing app. Your reception desk's browser-based scheduling tool. Every single one of those is a web application — and every single one is a potential entry point for the OWASP Top 10.

🦷
FROM THE DENTIST'S SIDE OF THE DRILL

I've run web application penetration tests against practice management portals and booking systems used by South African medical and dental practices. What I find routinely isn't sophisticated zero-days. It's OWASP Top 10 basics — the same vulnerabilities that have been on that list for years, sitting open and unaddressed. This article walks through each one, what it means in practice, and exactly what an attacker does with it.

#1
Broken Access Control — most common OWASP finding, present in 94% of tested apps
40×
Medical records worth more than credit card data on dark web markets
R10M
Maximum POPIA administrative fine for non-compliance after a breach
10
Vulnerability classes. Every single one is directly applicable to a medical practice web app.

A01 — Broken Access Control

01
OWASP A01:2021 · CRITICAL
Broken Access Control
MOST COMMON
SEVERITY

Access control means "this user should only see their own data." Broken access control means that restriction isn't enforced properly. It's the number one finding in modern web app testing — present in 94% of applications tested according to OWASP data.

In a medical or dental context, the scenario is brutally straightforward. Your patient portal shows appointment history and clinical notes at a URL like https://portal.yourpractice.co.za/patient/records?id=1042. An attacker logs in as patient 1041, then simply changes that ID to 1043, 1044, 1050, 1100. If the server doesn't verify that the logged-in user actually owns record 1042 — it just returns it — every patient file in your system is exposed. This is called an Insecure Direct Object Reference (IDOR), and it is shockingly common.

I have found IDOR vulnerabilities in South African practice management portals where changing a single integer in a URL exposed the full clinical history, identity documents, and medical aid details of a completely different patient. No hacking tools required. Just a browser and curiosity.

HTTP · IDOR ATTACK EXAMPLE
# Attacker is legitimately logged in as patient ID 1041 # They notice the URL structure while viewing their own records GET /patient/records?id=1041 HTTP/1.1 Host: portal.yourpractice.co.za Cookie: session=eyJhbGciOiJIUzI1NiJ9... # Response: Their own records. Now they try: GET /patient/records?id=1042 HTTP/1.1 ← Someone else's record GET /patient/records?id=1 HTTP/1.1 ← Probably the first patient ever registered GET /patient/records?id=9999 HTTP/1.1 ← Iterate. Automate. Exfiltrate. # With Burp Suite Intruder, they automate this in seconds: # 200 OK → record exists and is returned # 403 Forbidden → proper access control (rare) # In a typical vulnerable portal: 200 OK on every request. # Result: Full database dump of every patient record. No brute force. # No malware. One browser. Five minutes.

The POPIA angle: Under POPIA, you are the Responsible Party for every patient record you hold. An IDOR vulnerability that exposes patient data is a security compromise. You are legally obligated to report it to the Information Regulator within 72 hours of becoming aware of it, notify affected patients, and demonstrate that you had reasonable security measures in place. "We didn't know about it" is not a defence — a pentester would have found it in five minutes.

IDOR FORCED BROWSING PRIVILEGE ESCALATION POPIA S22

A02 — Cryptographic Failures

02
OWASP A02:2021 · HIGH
Cryptographic Failures
SEVERITY

Previously called "Sensitive Data Exposure," this category covers all the ways that data is inadequately protected in transit or at rest — weak encryption, no encryption, deprecated algorithms, or improper key management. For healthcare, where the data is about as sensitive as it gets, getting this wrong is catastrophic.

The most common finding in practice portals? Passwords stored as MD5 hashes. MD5 is not a password hashing function — it's a checksum. It's fast to compute, which is terrible for password storage, and there are precomputed lookup tables (rainbow tables) for billions of common passwords. If an attacker dumps your user database through a SQL injection (see A03), MD5 password hashes are cracked in minutes using tools like Hashcat on a modern GPU.

Also common: web apps that transmit patient data over HTTP instead of HTTPS — or that have HTTPS but accept insecure HTTP too without redirecting. On an open network (coffee shop, your own waiting room WiFi), a man-in-the-middle attacker intercepts the plaintext and reads everything in real time.

BASH · MD5 CRACK WITH HASHCAT
# Attacker obtains leaked DB dump — finds MD5 password hashes # Example hash for "Welcome1" (the most common SA corporate password) 5f4dcc3b5aa765d61d8327deb882cf99 ← MD5 of "password" e6d7e7f7c3f49b7c0f7b54543b8b5b5c ← MD5 of "Welcome1" d8578edf8458ce06fbc5bb76a58c5ca4 ← MD5 of "qwerty" # Hashcat with rockyou wordlist — RTX 4090 cracks billions/sec for MD5 hashcat -m 0 hashes.txt rockyou.txt 5f4dcc3b5aa765d61d8327deb882cf99:password ← CRACKED in 0.001s e6d7e7f7c3f49b7c0f7b54543b8b5b5c:Welcome1 ← CRACKED in 0.001s # Correct approach — bcrypt with cost factor 12: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewKyBAAmijXN5P5e # Same GPU: ~200 hashes/second. Wordlist attack becomes infeasible.
WEAK HASHING PLAINTEXT TRANSMISSION HTTP MIXED CONTENT RAINBOW TABLES

A03 — Injection

03
OWASP A03:2021 · CRITICAL
Injection (SQL, NoSQL, OS, LDAP)
DB DUMP RISK
SEVERITY

SQL injection has been on the OWASP list since its inception. It should be effectively extinct by now. It isn't. SQL injection is still found in production healthcare web apps, and when it is present in a medical practice portal, it means the attacker can dump the entire patient database in one command.

The attack works when user-supplied input — a name, a date, an ID number in a search field — is concatenated directly into a SQL query without sanitisation. The attacker injects SQL syntax into that input, changing the logic of the query itself. Against a practice portal with a patient search field, this can mean: authenticate without a password, extract every patient record, read files from the server, or in some configurations execute operating system commands.

SQL · INJECTION ATTACK — PATIENT PORTAL SEARCH
-- Vulnerable PHP backend query (what the dev wrote): $query = "SELECT * FROM patients WHERE surname = '" . $_GET['name'] . "'"; -- Normal request: ?name=Nkosi SELECT * FROM patients WHERE surname = 'Nkosi' -- Attacker's input: ?name=' OR '1'='1 SELECT * FROM patients WHERE surname = '' OR '1'='1' -- '1'='1' is always true → returns ALL patient records -- Extracting database version + all table names: -- ?name=' UNION SELECT table_name,2,3,4 FROM information_schema.tables-- SELECT * FROM patients WHERE surname='' UNION SELECT table_name... -- SQLmap automates all of this in one command: sqlmap -u "https://portal.practice.co.za/search?name=test" --dump-all # Result: Full DB dump. Every patient. Every record. Every password hash. # Elapsed time on a typical small-practice DB: under 4 minutes.

XSS (Cross-Site Scripting) also falls in this category. An attacker injects malicious JavaScript into a field your practice app displays to other users — a patient name, an appointment note, a referral comment. When a receptionist or doctor opens that record, the script executes in their browser, stealing their session cookie and giving the attacker full access to their authenticated session. From the server's perspective, the attacker is the doctor.

SQL INJECTION XSS SQLMAP SESSION HIJACKING

A04 — Insecure Design

04
OWASP A04:2021 · HIGH
Insecure Design
SEVERITY

This is the one that can't be patched. Insecure design means the security flaw is architectural — it was baked into the design of the application before a single line of code was written. You can patch a missing input validation check. You cannot patch a fundamentally broken trust model.

Classic example for practices: an online appointment booking system that sends a confirmation email with a "cancel appointment" link. The link is https://book.practice.co.za/cancel?appt=8842. No authentication. No token. Just the appointment ID. Any person who guesses or enumerates that ID can cancel any patient's appointment — including cancelling every appointment in your schedule for the next month. Or, more sinisterly, cancelling specific patients' oncology follow-ups or post-surgical check-ins.

Another insecure design pattern common in local practice management systems: the "forgot password" flow uses a predictable reset token — based on the patient's ID number and the timestamp, for example. An attacker who can guess or obtain a patient's ID number can generate a valid reset token themselves and take over the account without ever receiving the email.

THREAT MODELLING INSECURE TOKENS UNAUTHENTICATED ACTIONS DESIGN FLAW

A05 — Security Misconfiguration

05
OWASP A05:2021 · HIGH
Security Misconfiguration
SEVERITY

The most democratised vulnerability on the list. You don't need a developer to introduce it — anyone who deploys software can misconfigure it. And in a small medical practice where the IT was "set up by a guy" years ago and nobody has touched it since, security misconfiguration is almost guaranteed.

The scenarios I encounter most often: cloud-hosted practice management software with the admin panel exposed on the public internet at /admin with default credentials (admin/admin or admin/password). Web servers with directory listing enabled — visit a folder URL and the server helpfully lists every file inside it, including database backups. Error messages in production that display full stack traces with database connection strings, file paths, and framework versions — a roadmap for the next attack.

BASH · COMMON MISCONFIGURATION DISCOVERY
# Gobuster: brute-force hidden directories and admin panels gobuster dir -u https://portal.yourpractice.co.za -w /usr/share/wordlists/dirb/common.txt /admin (Status: 200) ← Admin panel — publicly accessible /backup (Status: 200) ← Backup folder with directory listing ON /phpinfo.php (Status: 200) ← PHP config dump, DB creds visible /.env (Status: 200) ← Environment file: DB password, API keys /db_backup_2024.sql (Status: 200) ← Entire patient database. Downloadable. # The .env file contents: DB_HOST=localhost DB_USER=practiceadmin DB_PASS=Practice@2023! ← Now attacker has full DB access MAIL_PASSWORD=smtp_secret_key

A .env file left in a public web directory is a single file that hands the attacker your database password, your email credentials, your API keys, and sometimes your cloud storage access. It happens constantly. I have found them on South African medical web apps. The file is often left there by a developer during setup and simply forgotten.

DEFAULT CREDS EXPOSED .ENV DIRECTORY LISTING GOBUSTER

A06 — Vulnerable & Outdated Components

06
OWASP A06:2021 · HIGH
Vulnerable & Outdated Components
SEVERITY

Modern web applications aren't written from scratch — they're assembled from components: frameworks, libraries, plugins, CMSs, third-party integrations. Every component has its own vulnerability history. Running an outdated version of any component means every known vulnerability in that version is available to an attacker who can look it up on a CVE database in 30 seconds.

The classic South African healthcare web app scenario: a practice website or portal built on WordPress with outdated plugins. WordPress itself is fine when maintained. But "contact form by practice admin," "appointment booking plugin v2.1 (2019)," and "PDF attachment handler v1.3" — all unpatched for three years — each carries known exploits. The WPScan tool enumerates every installed plugin and theme, identifies versions, and cross-references against a vulnerability database. It takes about ninety seconds.

BASH · WPSCAN AGAINST A PRACTICE WORDPRESS SITE
wpscan --url https://www.yourpractice.co.za --enumerate p,t,u [+] WordPress version 6.1.1 identified ← 3 versions behind, known vulns [+] Plugin: contact-form-7 v5.3.2 | [!] Title: Unrestricted File Upload → RCE | Fixed in: 5.3.3 | CVE: CVE-2020-35489 · CVSS: 9.8 CRITICAL [+] Plugin: booking-appointments v2.1.0 | [!] Title: SQL Injection via booking fields | CVE: CVE-2021-24145 · CVSS: 9.8 CRITICAL [+] Users: admin, drsmith, receptionist ← Username enumeration # Contact Form 7 CVE-2020-35489: upload a .php file disguised as an image # Server executes it. Attacker now has a web shell on your server. # Game over. Full server access. Patient data. Everything.
CVE DATABASE RCE WPSCAN UNPATCHED PLUGINS

A07 — Identification & Authentication Failures

07
OWASP A07:2021 · HIGH
Identification & Authentication Failures
SEVERITY

This covers every failure in the authentication and session management layer — weak passwords allowed, no rate limiting on login attempts, insecure "remember me" tokens, sessions that don't expire, and session IDs exposed in URLs. For a practice portal, authentication is the front door. If it's broken, everything inside is accessible.

The most immediately dangerous issue here is credential stuffing. Your receptionist's login for the practice portal is [email protected] / Welcome1! — the same password she uses for her personal Gmail, her Takealot account, and three other services. Two of those services have been breached; her credentials are in the RockYou2024 compilation. An attacker runs an automated credential stuffing tool against your portal's login endpoint with a list of known-breached email/password pairs. No brute force. No guessing. Known working credentials, tested against your system at 500 attempts per minute because there's no rate limiting and no MFA.

ROCKYOU2024: THE CONTEXT

The RockYou2024 compilation, released in mid-2024, contains approximately 10 billion unique plaintext passwords from thousands of data breaches. Your staff's old passwords are almost certainly in it. Credential stuffing tools load this list and test login endpoints automatically — your portal has no idea it's not a real user logging in unless you implement rate limiting, CAPTCHA, and MFA.

CREDENTIAL STUFFING NO MFA NO RATE LIMITING SESSION FIXATION

A08 — Software & Data Integrity Failures

08
OWASP A08:2021 · HIGH
Software & Data Integrity Failures
SEVERITY

This category covers assumptions about software updates, CI/CD pipelines, and serialised data — all without verifying integrity. The most famous real-world example is the SolarWinds supply chain attack, where attackers compromised a software vendor's build process and pushed malicious updates to thousands of organisations. Every one of those organisations automatically trusted and installed the update because it came from a trusted source.

For a medical practice, the most relevant scenario is insecure deserialisation in practice management APIs. Your practice management system might transmit session data or user preferences as a serialised object in a cookie or API request. If the server deserialises that data without validating it first, an attacker can craft a malicious serialised object that, when deserialised, executes arbitrary code on the server. It's an arcane attack, but the impact is remote code execution — the highest possible severity.

More practically: if your practice uses a third-party billing integration or pathology lab API that pulls a JavaScript library from an external CDN without a Subresource Integrity (SRI) hash, and that CDN is compromised, malicious JavaScript runs in every staff member's browser who opens the billing page. Skimming patient card details. Exfiltrating data. In real time.

SUPPLY CHAIN INSECURE DESERIALISATION NO SRI HASHES RCE RISK

A09 — Security Logging & Monitoring Failures

09
OWASP A09:2021 · MEDIUM-HIGH
Security Logging & Monitoring Failures
SEVERITY

This one is subtle. It doesn't let attackers in — but it's what allows them to stay in undetected. The global average dwell time for an attacker in a network is over 200 days. That's more than six months between initial compromise and detection. In a practice with no logging and no monitoring, that number could be indefinitely longer — or forever.

What this means practically: the IDOR attack in A01 enumerated 500 patient records. No alert was raised. The failed login attempts from credential stuffing in A07 — 3,000 attempts in twenty minutes from a Romanian IP — generated no alert. The attacker who finally authenticated with a stolen credential and has been browsing patient files for three weeks? No audit trail, no anomaly detection, nothing.

Under POPIA Section 22, you must notify the Information Regulator and affected data subjects "as soon as reasonably possible" after becoming aware of a compromise. If you have no logs, you never become aware. You also cannot fulfil your notification obligation, demonstrate the scope of the breach, or prove what data was and was not accessed. In a regulatory investigation, that absence of evidence becomes evidence of negligence.

⚠️
THE POPIA LOGGING OBLIGATION

The Information Regulator's guidance makes clear that adequate security measures include the ability to detect and respond to incidents. A practice that cannot demonstrate it logged access to patient data — and would not have known if that data was accessed — is in a difficult position when a breach is reported by a third party (like a patient who received phishing emails using information only in your records). Implement access logging. Now.

AUDIT LOGS DWELL TIME POPIA S22 NO ALERTING

A10 — Server-Side Request Forgery (SSRF)

10
OWASP A10:2021 · HIGH
Server-Side Request Forgery
SEVERITY

SSRF earned its place on the 2021 list after being weaponised in some of the most significant breaches of recent years — including the Capital One AWS breach in 2019. It's less well known to non-security practitioners, but it's particularly dangerous in cloud-hosted healthcare applications.

The attack works like this: your practice's patient portal has a feature that fetches an external URL — perhaps to display a referral PDF from a pathology lab, or to pull a profile photo from a URL, or to preview a link a patient submits. The attacker supplies not an external URL, but an internal one: http://169.254.169.254/latest/meta-data/. On AWS, that address is the Instance Metadata Service — it returns the server's IAM credentials, which can be used to access your entire AWS account, including any S3 buckets holding patient backups.

HTTP · SSRF AGAINST AWS METADATA SERVICE
# Vulnerable endpoint: portal fetches a URL and displays contents POST /portal/fetch-document HTTP/1.1 Content-Type: application/json {"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"} # Server (running on AWS EC2) makes that request internally # Response returned to attacker: { "Code": "Success", "AccessKeyId": "ASIA5EXAMPLE", "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "Token": "AQoDYXdzEJr...(long token)", "Expiration": "2026-03-03T18:00:00Z" } # Attacker now uses these credentials with AWS CLI: aws s3 ls ← Lists all S3 buckets in your account s3://practice-patient-backups-2024 ← There it is. aws s3 sync s3://practice-patient-backups-2024 ./loot ← Done.
SSRF AWS METADATA CLOUD PIVOT IAM CREDENTIALS
WHAT ABOUT THE OTHERS? — A QUICK NOTE

The OWASP list also includes entries we haven't given a full card to here. A04: Insecure Design and A08: Integrity Failures were covered above. The full 2021 list rounded out with these ten is the definitive reference — and every single one maps to real attack scenarios in healthcare web apps. For a full technical breakdown of any specific vulnerability category, book a consultation or check the OWASP documentation directly at owasp.org.

Hardening Your Practice Web Apps

The OWASP Top 10 isn't a counsel of despair. Every vulnerability on the list has well-established mitigations. The problem in small healthcare practices isn't that the fixes are complicated — it's that nobody is looking. Here's the starting checklist.

01
ENFORCE OBJECT-LEVEL AUTHORISATION ON EVERY API ENDPOINT
Every request that returns patient data must verify that the authenticated user owns that specific record. Not just "are you logged in" — "do you own record ID 1042?" This must be enforced server-side. It cannot be enforced client-side. If you use a practice management portal, ask your vendor directly: "How do you prevent IDOR?" If they don't know what that means, escalate.
02
HASH PASSWORDS WITH BCRYPT, ARGON2, OR SCRYPT — NEVER MD5 OR SHA1
If your system still stores MD5 or SHA1 password hashes, force a password reset for all users and migrate to bcrypt with a cost factor of at least 12. Enforce HTTPS everywhere — no mixed content, HSTS headers enabled, TLS 1.2 minimum (TLS 1.3 preferred). If your vendor can't confirm how passwords are stored, that is a critical finding.
03
USE PARAMETERISED QUERIES — NO EXCEPTIONS
SQL injection is 100% preventable with parameterised queries (prepared statements). User input never goes directly into a SQL string. If you have developers building your portal, this is non-negotiable. If you're using off-the-shelf software, run SQLmap against it yourself in a test environment, or have a pentester do it. If it's injectable, your vendor needs to fix it immediately.
04
ENFORCE MFA ON ALL STAFF ACCOUNTS — NO EXCEPTIONS
Multi-factor authentication defeats credential stuffing completely. Even if an attacker has your receptionist's exact email and password from a data breach, they cannot log in without the second factor. TOTP authenticator apps (Google Authenticator, Authy) are free and take ten minutes to set up. If your practice management portal doesn't support MFA, tell your vendor it's a requirement and document that conversation in writing for POPIA purposes.
05
REMOVE .ENV FILES, BACKUPS, AND DEBUG ENDPOINTS FROM WEB ROOTS
Run Gobuster or Nikto against your own domain. If it finds .env, phpinfo.php, /admin with default credentials, or SQL backup files downloadable over HTTP — those must be removed or secured immediately. Disable directory listing on your web server. Remove all debug error output from production (use generic error pages). Disable server version headers (Apache/2.4.41 in your HTTP response is a free invitation to search for CVEs for that exact version).
06
UPDATE EVERY PLUGIN, THEME, AND FRAMEWORK — WEEKLY
If your practice website runs WordPress, enable automatic updates for WordPress core, plugins, and themes. Uninstall every plugin you're not actively using — a deactivated plugin with a known RCE vulnerability is still exploitable. Subscribe to vulnerability notification services for your specific stack. Run WPScan against your own site monthly. Any critical CVE on an installed component gets patched within 24 hours, not "when we get around to it."
07
IMPLEMENT LOGGING AND SET UP ALERTING FOR SUSPICIOUS PATTERNS
Log every authentication attempt (success and failure) with IP, timestamp, and user agent. Log every access to patient records — who, when, which record. Set up alerts for: more than 10 failed logins from a single IP within 5 minutes; access to more than 20 patient records in a single session; logins from unusual geographic locations; any access outside business hours. This is your intrusion detection system. It also satisfies your POPIA obligation to demonstrate reasonable security measures and enables the Section 22 notification process if a breach occurs.
08
BLOCK SSRF — VALIDATE AND RESTRICT ALL SERVER-SIDE URL FETCHES
If your application fetches external URLs (document preview, profile images, webhook callbacks), implement an allowlist of permitted domains. Block all requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and the AWS metadata address (169.254.169.254). If you're on AWS, enable IMDSv2 (which requires a session token for metadata access and defeats most SSRF attacks against the metadata service). If you don't know whether your application fetches external URLs, ask your developer or vendor.

The Bottom Line

The OWASP Top 10 is not a new list. A01: Broken Access Control has been the most common web app vulnerability for years. A03: Injection has been on the list since OWASP's inception over twenty years ago. These aren't obscure, exotic attack classes discovered by nation-state actors — they're basic, well-documented, highly automatable vulnerabilities that free tools can identify in minutes.

The reason they persist in healthcare web apps isn't technical complexity. It's a combination of three things: vendors who don't prioritise security, practices who don't ask the right questions of their vendors, and nobody running even basic tests against the web-facing attack surface. A thirty-minute scan with free tools — Gobuster, SQLmap, WPScan — will tell you more about your web app security posture than most practices have ever known about theirs.

Under POPIA, you are not required to be perfect. You are required to have taken reasonable security measures. An IDOR vulnerability that exposes patient records, or an injectable patient search field, or a WordPress installation running plugins with CVSS 9.8 critical CVEs — none of those are defensible as "reasonable security measures." The Information Regulator will not accept "we didn't know" when a pentester would have found it in under an hour.

🛡️
WANT YOUR WEB APPS TESTED?

I test medical and dental practice web applications specifically — patient portals, booking systems, billing integrations, practice management web interfaces. I know the platforms, I know the common vulnerabilities, and I know what the Information Regulator expects. A web application penetration test against your practice's external-facing apps, documented with a professional report for POPIA compliance purposes, takes one to two days. Get in touch to discuss scope and pricing.