The Attack Happened Before You Even Noticed
On May 13, 2017, the IT department at Equifax noticed something unusual in their web traffic logs. By the time they traced it, attackers had been inside the network for over two months, quietly siphoning the names, Social Security numbers, birth dates, and financial records of 147 million Americans.
The cause? A single unpatched library. A known, public vulnerability in Apache Struts, with a patch that had been available for over 60 days, had been left unaddressed. One missed update. One forgotten component. Over 100 million people's lives disrupted.
This was not a case of exotic hacking techniques or nation-state sophistication. It was textbook application security failure.
And the uncomfortable truth is: it happens every day, in applications built by developers who believe their code is "good enough."
What Is Application Security?
Application security is the discipline of designing, building, testing, and maintaining software systems in a way that protects users, data, and systems from unauthorized access, exploitation, and attack throughout the entire software lifecycle.
It is not a feature you add at launch. It is not a firewall setting or a checkbox in a deployment form. Application security is a mindset: a set of engineering habits, testing practices, and architectural decisions that make the difference between software that holds up under attack and software that becomes the next breach headline.
The field is organized around two foundational tools:
- The OWASP Top 10: a globally maintained, data-backed list of the most critical and most commonly exploited web application vulnerabilities.
- Secure Coding Principles: a set of engineering guidelines that prevent vulnerabilities from entering your codebase in the first place.
Together, they form the foundation of a discipline that every developer, system administrator, and computer science student must understand, because in the modern world, writing software without understanding security is like building a house without understanding load-bearing walls.
The OWASP Top 10: Know What Attackers Know
The Open Worldwide Application Security Project (OWASP) is a non-profit foundation that has spent decades documenting how real attackers break into real applications. Their Top 10 list, updated every few years based on data from hundreds of organizations and thousands of breaches, is now the industry standard for understanding web application risk.
Here are the three vulnerabilities that deserve every developer's immediate attention:
1. Broken Access Control: The #1 Vulnerability in the World
In 2021, OWASP moved Broken Access Control to the number one position, the most widespread and impactful web vulnerability category. The reason it tops the list is simple: it is devastatingly easy to get wrong, and the consequences are catastrophic.
What it means: Users can act outside their intended permissions. A regular user can view another user's private data. A customer can access the admin dashboard. A student can see another student's grades, just by changing a number in the URL.
Consider this scenario. You log into an online portal and see your profile at:
https://portal.example.com/user/profile?id=1042What happens if you change 1042 to 1043? In a poorly secured system, you see someone else's profile: their name, contact details, academic records. This is called an Insecure Direct Object Reference (IDOR), and it is one of the most common causes of data breaches in web applications today.
The fix is conceptually simple, but requires discipline: Never use user-supplied input to authorize access to data. The server must always verify: "Does the currently authenticated user have permission to see this specific record?" That check must happen on the server side, every single time, with zero trust placed in the client.
# VULNERABLE: The user controls which record they see
def get_profile(user_id):
return db.query("SELECT * FROM users WHERE id = " + user_id)
# SECURE: The user can only see their own record
def get_profile():
user_id = session['authenticated_user_id']
return db.query("SELECT * FROM users WHERE id = ?", (user_id,))2. SQL Injection: The Oldest Attack That Still Works
In 2008, attackers breached Heartland Payment Systems, at the time the fifth largest payment processor in the United States. They stole the credit card data of 130 million people. The method was SQL Injection, a technique that had been publicly documented since the 1990s.
SQL Injection happens when an application takes user input and directly embeds it into a database query, allowing the attacker to break out of the data context and write their own commands.
Here is what that looks like in practice:
-- The developer intended this query:
SELECT * FROM users WHERE username = 'adam' AND password = 'mypassword';
-- But an attacker enters: ' OR '1'='1' --
-- The resulting query becomes:
SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = 'anything';
-- '1'='1' is always true -> login bypassed completelyThis is not a subtle exploit. It requires zero specialized tools. And yet, nearly two decades after Heartland, SQL Injection remains in the OWASP Top 10. The reason? Developers still write code that concatenates user input directly into queries.
The definitive fix: Use parameterized queries, always.
# VULNERABLE: never do this
cursor.execute("SELECT * FROM users WHERE username = '" + username + "'")
# SECURE: parameterized query; user input is data, never code
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))Parameterized queries separate SQL code from user data at the database engine level, making injection structurally impossible.
3. Cryptographic Failures: The False Promise of Encryption
In 2014, eBay disclosed a breach that exposed the account data of 145 million users. The passwords were encrypted, but the disclosure still rocked public trust, because the breach itself revealed deeper failures: attacker access had gone undetected for months, the notification timeline was inadequate, and the password hashing was not strong enough to protect against modern cracking tools.
Cryptographic failures are not just about using or not using encryption. They are about using it correctly:
- Storing passwords with MD5 or SHA-1 is not security. These algorithms are designed for speed, not resistance to brute force. Modern GPU-based cracking tools can test billions of MD5 hashes per second.
- Transmitting sensitive data over HTTP instead of HTTPS exposes it to interception.
- Hardcoded API keys in source code, committed to a public GitHub repository, give attackers instant access to cloud infrastructure.
The secure alternative: Use bcrypt, Argon2, or PBKDF2 for password hashing. These are intentionally slow, computationally expensive, and designed specifically for the purpose. Use TLS 1.3 for all data in transit. Use a secrets manager (AWS Secrets Manager, HashiCorp Vault) instead of hardcoded credentials.
Secure Coding Principles: Building Defense In
The OWASP Top 10 tells you what attackers exploit. Secure coding principles tell you how to write code that is resistant to those attacks from the start.
These are not optional guidelines. They are engineering discipline: the same way a structural engineer follows load calculations, a security-conscious developer follows these principles on every feature, every sprint, every line of code.
Input Validation means never trusting user-supplied data. Every input must be validated on the server side for type, length, format, and acceptable range, regardless of what the client already checked. Client-side JavaScript validation is a UX convenience. It is not a security control.
Least Privilege means granting the minimum access necessary. Your web application's database user should be able to SELECT, INSERT, UPDATE, and DELETE the records it needs, and nothing else. It should not have DROP TABLE, GRANT, or CREATE access. When an attacker compromises the app, they get the app's permissions and nothing more.
Defense in Depth means layering controls so that no single failure leads to total compromise. A firewall protects the perimeter. A WAF filters application-layer attacks. Input validation catches malformed data. Parameterized queries prevent injection. Even if one layer fails, the others hold.
Fail Securely means that when an error occurs, the system defaults to the most restrictive, safest state. An authentication error should deny access, never grant it. An exception in an authorization check should lock the door, not leave it open.
Don't Trust the Client is perhaps the most important principle for web developers. Anything that comes from the browser (form fields, cookies, HTTP headers, URL parameters, JSON payloads) can be manipulated by an attacker. The server must re-validate everything.
Security Belongs in the Development Process, Not at the End
For decades, security was treated as a final step: build the application, then have the security team test it before release. This model fails for one fundamental reason: fixing security vulnerabilities after code is written costs ten to one hundred times more than preventing them during development.
The Secure Software Development Lifecycle (S-SDLC) integrates security into every phase:
During requirements, security requirements are defined alongside functional requirements. During design, threat modeling identifies where attackers might strike, before a single line of code is written. During development, secure coding practices and code reviews catch vulnerabilities early. During testing, SAST (Static Application Security Testing) tools like SonarQube scan source code automatically, while DAST tools like OWASP ZAP simulate real attacks against the running application. During deployment, systems are hardened, unnecessary services are disabled, and configurations are reviewed. During maintenance, dependencies are monitored for new vulnerabilities and patched promptly.
This is the approach behind DevSecOps: the modern practice of embedding security tools directly into CI/CD pipelines, so every code push is automatically scanned, every dependency is checked, and every deployment is validated against security baselines.
The Uncomfortable Truth About "Secure Enough"
There is no such thing as a perfectly secure application. But there is a profound difference between applications built with security in mind and applications where security was never considered.
The OWASP Top 10 are not sophisticated, nation-state-level exploits. They are the attacks that automated scanners run against millions of websites every day. SQL Injection has been publicly documented for 25 years. Broken Access Control is conceptually simple to prevent. Outdated components can be identified by running a single dependency scan.
The applications that fall to these attacks are not breached because of advanced hacking. They are breached because a developer concatenated user input into a SQL query, or forgot to check authorization on an API endpoint, or left a library unpatched for 60 days.
Security is not someone else's problem. It is not the firewall team's responsibility. It is not a compliance checkbox. It is an engineering discipline, one that begins with the first line of code and never ends.
Activity: Identify the Vulnerability
Instructions: Read each scenario below. For each one: (1) Identify the OWASP Top 10 category, (2) Explain what went wrong, and (3) Propose a specific technical fix.
Scenario 1: A banking web app stores user passwords in its database as plain MD5 hashes. A developer argues, "At least they're not stored in plaintext." After a breach, attackers crack all passwords within 48 hours using a standard GPU cluster.
Scenario 2: A student portal allows users to view their own documents at /documents/view?file=student_2023001_grades.pdf. A student discovers that changing the filename in the URL gives full access to other students' documents.
Scenario 3: A developer builds a login form with JavaScript validation that checks for minimum password length before submission. They skip server-side validation because "the client-side check is already there."
Scenario 4: A company's web application uses a third-party library last updated in 2019. A critical vulnerability is disclosed in that library in 2022. The IT team is aware but has not patched it because "the system is working fine."
Discussion Question: If you were the security architect for Sorsogon State University's online portal, which three security controls would you implement first, and why?
Conclusion
Every time you write code, you are making a security decision, whether you realize it or not. Every time you concatenate user input into a query, you are choosing vulnerability. Every time you check authorization on the server, you are choosing protection. Every time you patch a dependency promptly, you are closing a door before attackers find it.
The OWASP Top 10 exists not to intimidate developers, but to focus attention where it matters most. The vulnerabilities on that list are not accidents: they are predictable, preventable, and the product of known, avoidable mistakes.
Application security is not about being perfect. It is about being intentional. It is about building systems where security is the default, where user data is treated as sacred, and where the question "how could this be attacked?" is asked at every stage of development, not only after the breach notification has been sent.
The next time you write a function that accepts user input, ask yourself: "What happens if this input is malicious?"
That question is where security begins.
References
- OWASP Top 10 (2021): https://owasp.org/www-project-top-ten/
- IBM Cost of a Data Breach Report (2023): https://www.ibm.com/reports/data-breach
- NIST Secure Software Development Framework: https://csrc.nist.gov/Projects/ssdf
- Verizon Data Breach Investigations Report (2023): https://www.verizon.com/business/resources/reports/dbir/
- OWASP Juice Shop (Hands-On Lab): https://owasp.org/www-project-juice-shop/
- Whitman, M. & Mattord, H. (2021). Principles of Information Security (6th ed.). Cengage Learning.
- Conklin, A. et al. (2021). Principles of Computer Security: CompTIA Security+ and Beyond. McGraw-Hill.