OWASP Top 10 - 2017
2017 Top 10 Web Application Security Risks
A1:Injection
Description
Injection vulnerabilities, appearing in various forms like SQL, NoSQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s malicious data can trick the interpreter into executing unintended commands or accessing data without proper authorization.
- This vulnerability primarily arises when applications fail to properly validate, filter, or escape user input before passing it to backend systems (databases, OS shells, etc.).
- Attackers can extract all information from a database, execute system commands, or access the file system through injected code, leading to extensive damage.
Prevention
The most crucial principle in defending against injection attacks is to clearly separate data from commands and queries.
- Use Parameterized Queries or Prepared Statements. This is the most effective method to prevent injections by forcing user input to be treated as data rather than part of the code.
- Special character filtering and escaping are essential. Use a whitelist approach to filter input values for only allowed character sets, and apply appropriate escaping based on the context (HTML, JavaScript, SQL, etc.).
- Always perform Server-Side Input Validation. Client-side validation can be bypassed, so the server must re-verify the validity and safety of input values.
- Apply the Principle of Least Privilege by granting database users and system accounts only the minimum necessary permissions.
- Conduct Source Code Review to identify potential injection vulnerabilities and utilize automated application security testing tools (SAST, DAST, IAST) to confirm vulnerabilities.
Attack Scenarios
Scenario #1: Database Exfiltration via SQL Injection An application’s forum search function directly includes user search queries in an SQL statement. An attacker injects malicious SQL code like
' OR '1'='1
into the search field, causing the query to always evaluate as true. This allows the attacker to view sensitive information, such as all user data and password hashes, from the database without authorization.1 2 3 4
// Vulnerable code example: String query = "SELECT * FROM products WHERE name LIKE '%" + userInput + "%'"; // If userInput is ' OR '1'='1: // SELECT * FROM products WHERE name LIKE '%' OR '1'='1%'
Scenario #2: Server Control via OS Command Injection An application receives a file name from a user and then executes a system command on the server to process that file. If the input is not properly validated, an attacker can append characters like
;
or&&
after the filename to inject arbitrary OS commands. For example, enteringfilename; rm -rf /
could attempt to delete all files on the server.
A2:Broken Authentication
Description
Broken Authentication occurs when functions related to authentication and session management in an application are implemented incorrectly. This allows attackers to compromise passwords, encryption keys, or session tokens, or to exploit other implementation flaws to temporarily or permanently assume other users’ identities.
- Brute-force Attacks and automated attacks against login mechanisms are primary causes of this vulnerability.
- Session IDs exposed in the URL or improper session invalidation (e.g., sessions remaining valid after logout) make systems vulnerable to session hijacking.
- This vulnerability arises when passwords are stored or transmitted in plain text or when weak hashing algorithms are used to protect passwords (e.g., using default and well-known credentials like
admin/admin
). - It occurs when password recovery or reset processes are insecurely implemented (e.g., security questions with easily guessable answers, or tokens that are short and predictable).
Prevention
To prevent authentication-related attacks, strong implementation of user identification, authentication, and session management is crucial.
- Whenever possible, implement Multi-Factor Authentication (MFA) to prevent brute-force attacks and credential reuse attacks. MFA makes it difficult for attackers to gain access even if they compromise a single factor.
- For administrator accounts, default credentials should not be used. Enforce strong password settings during deployment or require password changes for admin accounts.
- Enforce strong password combinations and implement measures to prohibit passwords found in lists of known weak passwords (e.g., OWASP Top 10,000 bad passwords).
- Implement limitations on failed login attempts (e.g., account lockout after a certain number of failures) or time delays to reduce the efficiency of brute-force attacks and prevent denial of service attacks.
- Implement secure session managers. After a successful login, generate a new, high-entropy session ID, ensure session IDs are not exposed in URLs, and immediately invalidate session IDs upon logout or after a period of inactivity.
- Passwords must be stored using secure, salted hashing methods (e.g., bcrypt, Argon2, PBKDF2).
Attack Scenarios
Scenario #1: Account Takeover via Credential Stuffing An attacker takes leaked username and password combinations from other websites and indiscriminately tries them on a specific application. If the application lacks login attempt limits or IP-based access restrictions, the attacker can find valid account credentials, hijack user sessions, and access sensitive information.
Scenario #2: Session Information Exposure and Hijacking A user logs into an application on a public computer and then simply closes the browser tab or leaves the computer without logging out. If session IDs are exposed in the URL or if the server-side lacks proper session timeout or invalidation policies, the next user who opens the same browser can access the service through the previous user’s authenticated session. This can lead to sensitive information leakage or account manipulation.
Scenario #3: Exploiting a Weak Password Recovery Mechanism An application’s password recovery feature relies on easily guessable security questions, such as “What is your mother’s maiden name?”. An attacker can use social engineering or publicly available information (e.g., social media) to find the victim’s answers, then reset the password and take over the victim’s account.
A3:Sensitive Data Exposure
Description
Sensitive Data Exposure occurs when many web applications and APIs fail to adequately protect sensitive data such as financial information, healthcare records, and Personally Identifiable Information (PII). Attackers may steal or modify such weakly protected data to conduct credit card fraud, identity theft, or other crimes. Sensitive data can be compromised without additional protection, such as encryption at rest or in transit, and requires special precautions when exchanged with the browser.
- Failure to encrypt sensitive data is the biggest flaw.
- Even when encryption is used, vulnerabilities are exacerbated by weak key generation and management, weak algorithms, protocols, and ciphers.
- Weak hashing storage techniques (e.g., using outdated hashing algorithms like MD5 or SHA1 without salting) have contributed to many of these vulnerabilities.
- Protocols that transmit data in plain text, such as HTTP, SMTP, and FTP, are risky for sensitive data transmission.
- You should verify if there is any sensitive data being processed in plain text during backup or storage.
- Ensure that weak cryptographic keys are not generated during key generation and management, and check if default keys are being reused.
- Furthermore, you can identify these vulnerabilities by checking whether user programs apply encryption using security directives or headers (e.g., HSTS), or whether there is a procedure to verify server certificate validity.
Prevention
The first step in protecting data is to understand its sensitivity level and handle it accordingly.
- Avoid storing unnecessary sensitive data, and strive to minimize such data. If data doesn’t exist, there’s no risk of it being stolen.
- Sensitive data must be protected using strong encryption techniques both at rest and in transit.
- Verify the use of modern, strong standard algorithms, protocols, and cryptographic keys, and ensure proper Key Management (e.g., key generation, storage, usage, and disposal).
- Use HTTPS (TLS/SSL) to encrypt all web traffic, and enforce clients to always use HTTPS connections by employing
HTTP Strict Transport Security (HSTS)
. - Store passwords using strong, salted hash functions like PBKDF2, bcrypt, scrypt, or Argon2, instead of insecure hashing methods (e.g., MD5, SHA1).
- Disable caching that contains sensitive data and ensure web server cache settings are secure.
- Be careful not to expose sensitive information in error messages or developer consoles.
Attack Scenarios
Scenario #1: Plaintext Credit Card Information Leakage A customer’s credit card information is stored in plaintext in an online shopping mall’s database, without encryption. If an attacker exploits an SQL injection vulnerability to access the database, they can easily steal all credit card information and use it for financial fraud.
Scenario #2: Sensitive Data Transmission over HTTP and Man-in-the-Middle Attack A user accesses a website that transmits sensitive personal information or login credentials over HTTP (rather than HTTPS). If an attacker performs a Man-in-the-Middle attack, they can intercept the plaintext data being transmitted, thereby stealing the user’s account or collecting personal information.
Scenario #3: Decryption of Weakly Hashed Passwords An application stores user passwords in its database by hashing them with MD5 without salting. If an attacker gains access to the database and steals the hashed passwords, they can easily decrypt the original passwords using a Rainbow Table Attack or a Brute-force Attack.
A4:XML External Entities (XXE)
Description
XML External Entities (XXE) vulnerabilities occur when many older or poorly configured XML processors evaluate external entity references within XML documents. External entities can be exploited to disclose internal files using the file URI
handler, access internal file shares, perform internal port scanning, achieve remote code execution, and launch denial of service attacks.
- Applications are vulnerable if they directly receive XML input, especially when uploading XML or inputting data from untrusted sources.
- Being vulnerable to XXE attacks means being vulnerable to denial-of-service (DoS) attacks, including the Billion Laughs Attack (XML Bomb). This attack uses numerous nested entity definitions to exhaust the XML parser’s memory, causing the service to crash.
Prevention
The core principle for preventing XXE attacks is to disable the external entity processing capabilities of XML parsers.
- Use less complex data formats like JSON or avoid using sensitive data in XML. Consider other data exchange formats when possible.
- Patch or upgrade XML processors and libraries to their latest versions. Newer versions typically provide built-in defenses against XXE attacks or allow for easy configuration of such defenses.
- If using SOAP (an XML-based messaging protocol), upgrade to SOAP 1.2 or higher.
- Use filtering and validation on the server to block malicious data in XML documents, headers, and nodes. This is part of strengthening input validation.
- When uploading XML files, use XSD (XML Schema Definition) validators to validate the structure and content of the uploaded XML document against a predefined schema.
- Disabling all DTD (Document Type Definition) processing is the most effective method. Most XML parsers provide options to disable DTD features, including external entities.
Attack Scenarios
Scenario #1: Internal File Access and Information Disclosure An application receives and parses an XML file from a user. The attacker defines an external entity within the XML document like
<!ENTITY xxe SYSTEM "file:///etc/passwd">
and then references this entity within the document. When the XML parser processes this external entity, the contents of the/etc/passwd
file are included in the application’s response and disclosed to the attacker. This can lead to the leakage of system user information or other sensitive files.Scenario #2: Denial of Service (DoS) Attack (Billion Laughs Attack) An attacker uses nested external entities to cause an XML parser to consume an enormous amount of memory when parsing a small XML document. For example, by having numerous entities reference each other (e.g.,
&lol9;
), the XML parser allocates excessive resources, leading the server to become unresponsive.
A5:Broken Access Control
Description
Broken Access Control frequently occurs when restrictions on what authenticated users are allowed to do are not properly enforced. Attackers can exploit these flaws to access unauthorized functionality and/or data, such as accessing other users’ accounts, viewing sensitive files, modifying other users’ data, or changing access rights.
- If it’s possible to view or edit information of other accounts, this vulnerability exists.
- If JWT (JSON Web Token) tokens can be replayed or tampered with, then access control has failed.
- Allowing access to unauthorized APIs is also a vulnerability. For instance, if a regular user role can call an API designed only for administrators.
- A default ‘allow’ policy might be set, meaning all access is permitted unless explicitly blocked by a ‘deny’ rule.
Prevention
Access control should be effectively applied only by trusted server-side code or serverless APIs, where attackers cannot modify access control checks or metadata.
- The default policy should be ‘deny’. This means applying the
deny-by-default
principle, where all access is denied unless explicitly permitted. - The access control model should enforce that only the record owner has permissions to create/read/update/delete specific records, rather than allowing any user to do so. This is crucial for preventing horizontal privilege escalation.
- Disable directory listing on web servers and ensure that metadata files like
.git
or backup files are not present in the web root. - JWTs should be immediately invalidated after logout and it is recommended to set a short validity period for them.
- All access control decisions must be made on the server side. Client-side access control can be easily bypassed.
- Implement proper logging and monitoring for access control failures to quickly detect and respond to suspicious activities.
Attack Scenarios
Scenario #1: Horizontal Privilege Escalation via URL Manipulation A user accesses a URL to view their profile, such as
https://example.com/profile?id=123
. An attacker changes theid
value to124
and sends a request tohttps://example.com/profile?id=124
. If the application does not properly verify that the user’s ID matches the requested profile ID, the attacker can view or modify other users’ profile information.Scenario #2: Insufficient Access Control for API Endpoints An application has an API endpoint,
GET /api/v1/users
, which returns a list of all users. Although this API was originally designed to be accessible only by administrators, the server-side lacks authorization validation for user roles, allowing regular users to call this API. An attacker can call this API to steal all user information from the system.Scenario #3: Access Bypass via HTTP Method Tampering A user sends a
GET /post/delete?id=123
request for a post they can only delete themselves. The server does not allow deletion forGET
requests. However, an attacker changes this request to aPOST
request. If the server does not properly implement access control forPOST
requests, the attacker can delete posts they do not own.
A6:Security Misconfiguration
Description
Security Misconfiguration is one of the most commonly observed security issues. It typically results from insecure default configurations, incomplete or ad hoc configurations, exposed cloud storage, misconfigured HTTP headers, and verbose error messages containing sensitive information. Not only must all operating systems, frameworks, libraries, and applications be securely configured, but they must also be patched/upgraded in a timely fashion.
- Systems are vulnerable if default accounts and passwords are enabled or used without being changed.
- It’s also risky if error handling exposes stack trace information or other data that could aid an attack (e.g., component versions, internal paths).
- This vulnerability applies if security settings are not configured or outdated versions are used on servers, frameworks, libraries, or databases.
- Unnecessary functions, services, or ports that are enabled increase the potential attack surface.
- This includes cases where security headers (e.g.,
Content-Security-Policy
,X-Content-Type-Options
,X-Frame-Options
) are improperly set or missing on web or application servers.
Prevention
To prevent security misconfiguration, it’s crucial to establish consistent and repeatable security configuration processes.
- Remove unnecessary features and components to maintain a minimal platform, and delete or avoid installing unused functionalities and frameworks.
- A proper review and update process for all security information, updates, and patches is essential. This should be included in regular vulnerability scanning and security auditing processes.
- Apply architectures that provide efficient and secure isolation through methods like segmentation, containerization, and cloud security groups.
- Establish automated procedures that can verify proper security settings in all environments (development, testing, production). This minimizes configuration errors during deployment.
- Default account passwords must be changed, and strong password policies should be enforced.
- Error messages should only provide general information, and sensitive details like stack traces or internal system information should not be exposed to users.
Attack Scenarios
Scenario #1: Web Server Directory Listing Allowed Due to a web server misconfiguration, directory listing is enabled. An attacker accesses directories like
/backup
or/temp
via a web browser and finds backup files (.bak
,.zip
) or configuration files (.config
,.env
) accidentally uploaded by developers. These files may contain sensitive credentials like database connection information or API keys, which the attacker can use to further penetrate the system.Scenario #2: Development/Sample Application Left on Production Environment A development-specific sample application or admin console is deployed on a production server and not removed. This sample application might use default passwords or contain known security vulnerabilities. An attacker can exploit these vulnerabilities or access it with default passwords to compromise the server.
Scenario #3: Public Access to Cloud Storage Bucket In an application storing data on a cloud service (e.g., AWS S3), the storage bucket’s access permissions are incorrectly set to Public Read/Write. An attacker can exploit this misconfiguration to view all sensitive data stored in the bucket or upload malicious files to deface the website or distribute malware.
A7:Cross-Site Scripting (XSS)
Description
Cross-Site Scripting (XSS) vulnerabilities occur whenever an application includes untrusted data in a new web page without proper validation or escaping, or updates an existing web page with user-supplied data using a browser API that can create HTML or JavaScript. XSS allows attackers to execute scripts in the victim’s browser, which can lead to hijacking user sessions, defacing websites, or redirecting the user to malicious sites.
- Generally, there are three main types of XSS:
- Reflected XSS: The attacker’s script is included in an HTTP request and immediately “reflected” back to the user via the server and executed. (e.g., malicious script embedded in a search results page).
- Stored XSS (Persistent XSS): The attacker’s script is stored on the server-side (e.g., in a database) and is executed later when other users are served that content. (e.g., inserting a malicious script into a forum post, comment, or profile information, which executes when other users view that page).
- DOM-based XSS: This occurs client-side, without the server. It happens when client-side script in a web page manipulates the DOM (Document Object Model) to handle user input insecurely. (e.g., client-side JavaScript uses a URL hash (
#
) value to dynamically generate page content, and a malicious script is included in this value).
Prevention
The core of defending against XSS attacks is to never trust user input and to properly handle it based on the context when it is outputted.
- Perform proper validation and escaping for all user input. Specifically, apply escaping appropriate to the output context (HTML context, JavaScript context, URL context, etc.).
- HTML Entity Encoding: When user input is outputted as HTML content, convert special characters like
&
,<
,>
,"
,'
,/
into HTML entities to prevent the browser from interpreting them as scripts.
- HTML Entity Encoding: When user input is outputted as HTML content, convert special characters like
- Implement a Content Security Policy (CSP): CSP helps mitigate XSS and other types of content injection attacks by restricting the origins from which web applications can load resources (scripts, stylesheets, images, etc.).
- Avoid using insecure JavaScript APIs (e.g.,
innerHTML
,document.write()
,eval()
). Instead, use safe APIs that only handle text content, such astextContent
orappendChild()
. - Protect cookies using the HTTPOnly attribute: Cookies set with the
HTTPOnly
flag cannot be accessed via JavaScript, which helps prevent session cookie theft through XSS attacks. - Input Validation: Perform input validation on both the client-side and server-side to minimize the malicious data entering the system.
Attack Scenarios
Scenario #1: Reflected XSS via Search Results Page A user enters a malicious script like
"><script>alert('XSS Attack');</script>
into a website’s search bar. The website reflects this input directly onto the search results page without proper escaping. As a result, when other users visit that page, thealert('XSS Attack')
script executes in their browsers, which could lead to session cookie theft or redirection to malicious sites.Scenario #2: Stored XSS via Forum Comments An attacker writes a forum comment that includes a malicious script like
<h1>Malicious Comment <script>fetch('/api/steal_cookie', {method: 'POST', body: document.cookie});</script></h1>
. This comment is stored in the database, and every time another user views that post, the script executes in their browser, sending their session cookie to the attacker’s server. The attacker can then hijack the user’s session using the stolen cookie and impersonate their account.Scenario #3: Client-Side DOM-based XSS A web page’s JavaScript code reads data from the URL’s
#
(hash) value and dynamically adds content to the page usingdocument.write()
. An attacker sends a malicious URL likehttp://example.com/page.html#<script>alert('XSS');</script>
to a user. When the user clicks this URL, the client-side JavaScript executes the script embedded in the#
value, leading to an XSS attack.
A8:Insecure Deserialization
Description
Insecure Deserialization is a vulnerability that occurs when serialized objects are deserialized insecurely. This often leads to Remote Code Execution (RCE), and even if deserialization flaws do not result in RCE, they can be used to perform various attacks, including replay attacks, injection attacks, and privilege escalation attacks.
- This attack is by no means easy and often occurs when developers do not properly understand the security implications of serialization/deserialization.
- Serialization is the process of converting an object into a sequence of bytes for storage or transmission across a network. Deserialization is the inverse process, converting the byte stream back into an object.
- If serialized data granting
user
privileges is transmitted, an attacker can tamper with it, and during the deserialization process, if it’s converted toadmin
privileges, a critical issue can arise. This is because untrusted data can be interpreted and executed as code during the deserialization process.
Prevention
The most potent method for defending against insecure deserialization attacks is to avoid deserializing objects from untrusted sources.
- Do not allow deserialization of objects from untrusted sources. This is the most effective defense.
- Implement digital signatures or integrity checks for serialized data to detect data tampering. If a signature is invalid or data is corrupted, reject deserialization.
- While it is good to impose restrictions on the classes that can be deserialized (e.g., whitelist-based class filtering), this is not a complete defense as bypass methods may exist.
- Monitor the deserialization process and alert if abnormal deserialization attempts occur continuously.
- Use secure serialization/deserialization libraries and educate developers to avoid using insecure functionalities.
- Ensure that the object graph does not contain classes that allow remote code execution (e.g.,
Runtime.exec()
,ProcessBuilder
).
Attack Scenarios
Scenario #1: Remote Code Execution via Java Deserialization A Java application uses
ObjectInputStream.readObject()
to deserialize objects transmitted from a user. An attacker leverages a known deserialization vulnerability in a library like Apache Commons Collections to create and send a serialized object containing a malicious payload to the application. During the deserialization of this object, the attacker’s intended arbitrary command is executed on the server, potentially leading to server compromise.Scenario #2: Privilege Escalation via .NET Deserialization A .NET application processes serialized data using
BinaryFormatter
. An attacker serializes a user object with administrative privileges and then modifies it before sending it to the application. When the application deserializes this object, the attacker can escalate their privileges from a regular user to an administrator, gaining access to sensitive functionalities.
A9:Using Components with Known Vulnerabilities
Description
Using Components with Known Vulnerabilities occurs when an application uses libraries, frameworks, and other software modules that have known security vulnerabilities but are not updated or properly patched. These components run with the same privileges as the application. Therefore, if a vulnerable component is exploited, such an attack can facilitate serious data loss or server takeover. Applications and APIs using components with known vulnerabilities may undermine application defenses and enable various attacks and impacts.
- Software that is vulnerable, no longer supported (End-of-Life), or an outdated version is highly likely to be vulnerable.
- Developers often hesitate to update newly upgraded libraries due to compatibility testing issues, leading to the continued use of vulnerable versions.
- Since components like libraries, frameworks, and other software modules run with the same privileges as the application, a vulnerability in any one of them can significantly impact the entire application.
Prevention
To prevent the use of components with known vulnerabilities, continuous monitoring and a systematic management process are essential.
- Remove unused components and keep the platform to a minimum. Reducing unnecessary dependencies is critical.
- Download components from official sources and verify package integrity (e.g., hash value verification, digital signature verification) to ensure no malicious code has been inserted.
- Continuously monitor vulnerability databases like CVE (Common Vulnerabilities and Exposures) and NVD (National Vulnerability Database), and subscribe to alerts for new security vulnerabilities in components you use to respond promptly.
- Use Software Composition Analysis (SCA) tools to identify and manage known vulnerabilities in open-source and third-party libraries.
- If patching is not feasible or realistic, consider mitigation strategies like Virtual Patching. This involves using web application firewalls (WAFs) to block attack patterns targeting vulnerabilities.
- All organizations must perform continuous monitoring, update checks, and configuration changes throughout the application’s lifecycle. Even in environments where regular patching is difficult or impossible, such as IoT devices or biomedical equipment, applying security patches can be crucial.
Attack Scenarios
Scenario #1: Exploiting an Outdated Web Server Library Vulnerability An application uses an outdated version of the Apache Struts framework, which has a known Remote Code Execution (RCE) vulnerability. An attacker exploits this vulnerability by sending a malicious HTTP request to the web server, which allows them to execute arbitrary code on the server. As a result, the attacker can completely take over the server, exfiltrate sensitive data, or deface the website.
Scenario #2: Malicious Code in npm Packages A developer downloads a popular JavaScript library from the npm registry to include in a web application. However, a specific version of this library contains a backdoor inserted by an attacker. Unaware of this, the developer deploys the application, and the backdoor is then used to transmit sensitive user information to an external server. This occurs because the origin of the component was not properly verified.
Scenario #3: Website Defacement via CMS Plugin Vulnerability On a website using a CMS (Content Management System) like WordPress, one of the installed plugins is an outdated version that hasn’t received the latest security patches. This plugin has a file upload vulnerability, which an attacker exploits to upload a web shell and use it to deface the website or inject malicious code.
A10:Insufficient Logging & Monitoring
Description
Insufficient Logging & Monitoring occurs when inadequate logging and monitoring are combined with ineffective integration with incident response. This allows attackers to further compromise systems, maintain persistence, pivot to more systems, and tamper with, extract, or destroy data. According to most breach studies, the average time to detect a breach is over 200 days, and breaches are typically detected by external parties (e.g., customers, regulatory bodies) rather than internal processes or monitoring.
- Insufficient logging and monitoring are foundational to all significant security incidents. These vulnerabilities allow attackers to remain undetected in the system for longer periods, causing greater damage.
- While logging too much unnecessary data is not ideal, critical events (e.g., login attempts, access control failures, critical data changes, administrative activities) must be recorded.
- Systems can be exposed to this vulnerability if logs for important activities like login and failed login attempts are not monitored, or if there are no log messages for warnings and errors, or if API call logs for suspicious activities are not monitored.
- If logs are stored only locally, and logging or alert events can be visible to users or attackers (e.g., detailed error logs displayed directly on a web page), this vulnerability exists. This provides attackers with useful system information.
Prevention
To defend against insufficient logging and monitoring vulnerabilities, you must establish systematic logging, centralized monitoring, and a rapid incident response process.
- Log all suspicious or malicious account activities that can identify such actions, including all logins, access control failures, and server-side input validation failures.
- Ensure logs are generated in a format that can be easily used by a centralized log management solution (e.g., SIEM, Splunk, ELK Stack) to implement security measures. This allows for efficient collection, storage, and analysis of logs.
- Logs should contain sufficient contextual information (e.g., timestamp, user ID, source IP address, requested URL, operation type, result, etc.).
- Protect log integrity. Prevent attackers from modifying or deleting logs (e.g., using WORM (Write Once Read Many) storage, encrypting and verifying integrity during log transmission, and controlling access to log servers).
- Establish near real-time monitoring and alerting systems to receive immediate notifications when suspicious activities occur (e.g., threshold-based alerts, anomalous behavior detection).
- Regularly analyze log data to identify patterns and detect abnormal activities.
- Develop an Incident Response Plan and integrate logging and monitoring systems into this plan to quickly detect and respond to breaches.
Attack Scenarios
Scenario #1: Undetected Persistent Data Exfiltration An attacker exploits an SQL injection vulnerability to access a database and continuously exfiltrate sensitive information. However, the application server’s logs lack records of abnormal database queries or large data transfers, or relevant alert systems are not configured. As a result, the attacker can continue to exfiltrate data undetected for months, causing significant damage to the organization.
Scenario #2: System Information Disclosure via Error Messages and Attack Foothold The application server exposes detailed error messages to users (e.g., stack traces, database connection information, internal IP addresses). These error messages provide hints about vulnerable component versions or the internal network structure of the server. If such information disclosure goes undetected due to insufficient logging and monitoring, the attacker can use this information to plan and execute the next phase of their attack.
Scenario #3: Successful Credential Stuffing Due to Lack of Login Failure Monitoring A large-scale credential stuffing attack occurs on an application’s login page. Tens of thousands of login attempts are made in a short period, but due to a lack of logging for failed login attempts or threshold-based monitoring, this abnormal activity goes undetected. Eventually, the attacker successfully logs into some accounts and hijacks sessions, but the system administrator remains unaware of the breach, allowing the damage to spread.
2017 Top 10 Web Application Security Risks
A1:Injection
Description
인젝션(Injection) 취약점은 SQL, NoSQL, OS, LDAP 인젝션 등 다양한 형태로 나타나며, 신뢰할 수 없는 데이터가 명령어(command) 또는 쿼리(query)의 일부로 인터프리터(interpreter)에 전송될 때 발생합니다. 공격자가 전송한 악의적인 데이터는 인터프리터를 속여 의도하지 않은 명령을 실행하거나, 적절한 권한 없이 데이터에 접근하게 만들 수 있습니다.
- 이 취약점은 애플리케이션이 사용자 입력값을 적절히 검증, 필터링, 또는 이스케이프(escaping) 처리하지 않고 백엔드 시스템(데이터베이스, OS 셸 등)으로 전달할 때 주로 발생합니다.
- 공격자는 주입된 코드를 통해 데이터베이스의 모든 정보를 추출하거나, 시스템 명령을 실행하거나, 파일 시스템에 접근하는 등 광범위한 피해를 유발할 수 있습니다.
Prevention
인젝션 공격을 방어하는 데 있어 가장 중요한 원칙은 데이터를 명령어와 쿼리로부터 명확하게 분리하는 것입니다.
- 매개변수화된 쿼리(Parameterized Queries) 또는 준비된 문(Prepared Statements)을 사용합니다. 이는 사용자 입력값이 코드의 일부가 아닌 데이터로 처리되도록 강제하여 인젝션을 방지하는 가장 효과적인 방법입니다.
- 특수 문자 필터링 및 이스케이프 처리가 필수적입니다. 입력값을 허용된 문자 집합에 대해서만 필터링하는 화이트리스트(whitelist) 방식을 사용하고, 해당 컨텍스트(HTML, JavaScript, SQL 등)에 적합한 이스케이프 처리를 적용합니다.
- 서버 측 입력 유효성 검사(Server-Side Input Validation)를 반드시 수행합니다. 클라이언트 측 유효성 검사는 우회될 수 있으므로, 서버에서 다시 한번 입력값의 유효성과 안전성을 확인해야 합니다.
- 최소 권한의 원칙(Principle of Least Privilege)을 적용하여 데이터베이스 사용자나 시스템 계정에 최소한의 필요한 권한만 부여합니다.
- 소스 코드 리뷰(Source Code Review)를 통해 잠재적인 인젝션 취약점을 식별하고, 자동화된 애플리케이션 보안 테스트(SAST, DAST, IAST) 도구를 활용하여 취약점을 확인합니다.
Attack Scenarios
Scenario #1: SQL 인젝션을 통한 데이터베이스 유출 게시판 검색 기능에서 사용자의 검색어 입력을 SQL 쿼리에 직접 포함하는 애플리케이션이 있습니다. 공격자는 검색어 입력란에
' OR '1'='1
과 같은 악성 SQL 코드를 주입하여 쿼리가 항상 참(True)이 되도록 만듭니다. 이로 인해 공격자는 의도치 않게 데이터베이스 내의 모든 사용자 정보, 비밀번호 해시 값 등 민감한 정보를 열람할 수 있게 됩니다.1 2 3 4
// 취약한 코드 예시: String query = "SELECT * FROM products WHERE name LIKE '%" + userInput + "%'"; // userInput에 ' OR '1'='1이 들어갈 경우: // SELECT * FROM products WHERE name LIKE '%' OR '1'='1%'
Scenario #2: OS 명령어 인젝션을 통한 서버 제어 애플리케이션이 사용자로부터 파일 이름을 입력받아 서버에서 해당 파일을 처리하는 시스템 명령어를 실행합니다. 만약 입력값이 적절히 검증되지 않으면, 공격자는 파일 이름 뒤에
;
또는&&
와 같은 문자를 추가하여 임의의 OS 명령어를 주입할 수 있습니다. 예를 들어,filename; rm -rf /
를 입력하여 서버의 모든 파일을 삭제하는 시도를 할 수 있습니다.
A2:Broken Authentication
Description
인증 깨짐(Broken Authentication)은 애플리케이션의 인증 및 세션 관리와 관련된 기능들이 부적절하게 구현될 때 발생합니다. 이는 공격자가 비밀번호, 암호화 키 또는 세션 토큰을 탈취하거나, 다른 구현상의 결함을 악용하여 다른 사용자의 신원을 일시적 또는 영구적으로 도용할 수 있게 만듭니다.
- 무차별 대입 공격(Brute-force Attacks) 및 자동화된 공격을 허용하는 로그인 메커니즘은 이 취약점의 주된 원인입니다.
- 세션 ID가 URL에 노출되거나, 세션 ID를 제대로 무효화시키지 않는 경우 (예: 로그아웃 후에도 세션이 유효한 경우) 세션 하이재킹에 취약해집니다.
- 평문(plain text)으로 비밀번호를 저장하거나 전송하거나, 취약한 해시 알고리즘을 사용하여 비밀번호를 보호할 때 이 취약점이 발생하게 됩니다. (예:
admin/admin
과 같은 기본적이고 잘 알려진 자격 증명을 사용하는 경우) - 비밀번호 복구 또는 재설정 프로세스가 안전하지 않게 구현될 때 (예: 보안 질문의 답변이 쉽게 추측 가능하거나, 토큰이 짧고 추측하기 쉬운 경우) 발생합니다.
Prevention
인증 관련 공격을 예방하기 위해서는 사용자 식별, 인증 및 세션 관리를 강력하게 구현해야 합니다.
- 가능하면 다단계 인증(Multi-Factor Authentication, MFA)을 구현하여 무차별 대입 공격 및 탈취된 자격 증명 재사용 공격을 예방합니다. MFA는 공격자가 단 하나의 요소를 탈취하더라도 계정에 접근하기 어렵게 만듭니다.
- 관리자 계정의 경우 기본 자격 증명(default credentials)을 사용하지 말아야 합니다. 배포 시 강력한 비밀번호 설정을 강제하거나, 관리자 계정의 기본 비밀번호를 변경하도록 요구해야 합니다.
- 비밀번호는 강력한 조합으로 사용하도록 강제하고, 알려진 취약한 비밀번호 목록(예: OWASP Top 10,000 bad passwords)에 포함된 비밀번호는 사용하지 못하도록 구현합니다.
- 로그인 실패에 대한 제한(예: 일정 횟수 실패 시 계정 잠금)이나 시간 지연(delay)을 두어 무차별 대입 공격의 효율성을 떨어뜨리고 서비스 거부 공격을 방지합니다.
- 세션 관리자를 안전하게 구현합니다. 로그인 성공 후에는 새로운 고 엔트로피(high-entropy) 세션 ID를 생성하고, 세션 ID가 URL에 노출되지 않도록 하며, 로그아웃하거나 일정 시간 비활성화 상태가 되면 세션 ID를 즉시 무효화해야 합니다.
- 비밀번호는 안전한 솔티드(salted) 해싱(예: bcrypt, Argon2, PBKDF2) 방식으로 저장해야 합니다.
Attack Scenarios
Scenario #1: 크리덴셜 스터핑 공격을 통한 계정 탈취 공격자가 다른 웹사이트에서 유출된 사용자 이름과 비밀번호 조합을 가지고와 특정 애플리케이션에 무차별적으로 대입합니다. 만약 애플리케이션이 로그인 실패 횟수 제한이나 IP 기반의 접근 제한이 없다면, 공격자는 유효한 계정 정보를 찾아내어 사용자의 세션을 하이재킹하고 민감한 정보에 접근할 수 있게 됩니다.
Scenario #2: 세션 정보 노출 및 하이재킹 사용자가 공용 컴퓨터에서 애플리케이션에 로그인한 후, 로그아웃 버튼을 누르지 않고 단순히 브라우저 탭을 닫거나 컴퓨터를 떠납니다. 만약 세션 ID가 URL에 노출되거나, 서버 측에서 적절한 세션 타임아웃 또는 무효화 정책이 없다면, 다음 사용자가 동일한 브라우저를 열었을 때 이전 사용자의 인증된 세션을 통해 서비스에 접근할 수 있게 됩니다. 이는 민감한 정보 유출이나 계정 조작으로 이어질 수 있습니다.
Scenario #3: 약한 비밀번호 복구 메커니즘 악용 애플리케이션의 비밀번호 복구 기능이 “어머니의 이름은?”과 같은 쉽게 추측 가능한 보안 질문에 의존합니다. 공격자는 소셜 엔지니어링이나 공개된 정보(SNS 등)를 통해 피해자의 답변을 알아낸 후, 이를 이용하여 비밀번호를 재설정하고 피해자의 계정을 탈취합니다.
A3:Sensitive Data Exposure
Description
민감 데이터 노출(Sensitive Data Exposure)은 많은 웹 애플리케이션과 API가 금융 정보, 건강 기록, PII(개인 식별 정보)와 같은 민감한 데이터를 적절하게 보호하지 않을 때 발생합니다. 공격자는 이렇게 약하게 보호되는 데이터를 훔치거나 변조하여 신용카드 사기, 신원 도용 또는 기타 범죄를 저지를 수 있습니다. 민감한 데이터는 저장 중(at rest) 또는 전송 중(in transit)에 암호화와 같은 추가적인 보호 없이는 침해될 수 있으며, 브라우저와 교환될 때 특별한 주의가 필요합니다.
- 민감한 데이터를 암호화하지 않는 것이 가장 큰 결함입니다.
- 암호화를 사용했을 때에도 취약한 키 생성 및 관리, 약한 알고리즘, 프로토콜 및 암호 사용으로 인해 취약점이 더 두드러집니다.
- 취약한 해싱 저장 기술 (예: 솔트(salt) 없이 MD5나 SHA1 같은 오래된 해싱 알고리즘 사용) 때문에 이러한 취약점이 많았습니다.
- HTTP, SMTP, FTP와 같이 평문으로 데이터를 전송하는 프로토콜은 민감 데이터 전송에 위험합니다.
- 백업 또는 저장 시 평문으로 처리되는 민감한 데이터가 있는지 확인해야 합니다.
- 키 생성 및 관리에서 약한 암호화 키를 생성하지 않는지 확인하고, 기본 키가 재사용되는지도 확인해야 합니다.
- 또한 사용자 프로그램에서 보안 지시문(directives)이나 헤더(예: HSTS)와 같은 암호화를 적용하고 있는지, 혹은 서버 인증서가 유효한지 확인하는 절차가 있는지를 통해 이러한 취약점이 있는지 점검할 수 있습니다.
Prevention
데이터를 보호함에 있어 가장 먼저 해야 할 일은 데이터의 민감도를 파악하고 그 분류에 따라 처리 방식을 달리하는 것입니다.
- 불필요한 민감한 데이터는 저장하지 않고, 그러한 데이터를 최소화하도록 노력합니다. 데이터가 없으면 탈취될 위험도 없습니다.
- 민감한 데이터는 저장 시(at rest)와 전송 시(in transit) 모두 강력한 암호화 기법을 사용하여 보호해야 합니다.
- 최신의 강력한 표준 알고리즘, 프로토콜, 암호화 키를 사용하는지 확인하고, 적절한 키 관리(Key Management)가 이루어져야 합니다. (예: 키 생성, 저장, 사용, 폐기 등)
- HTTPS (TLS/SSL)를 사용하여 모든 웹 트래픽을 암호화하고,
HTTP Strict Transport Security (HSTS)
를 사용하여 클라이언트가 항상 HTTPS 연결을 사용하도록 강제합니다. - 안전하지 않은 해싱 방식(예: MD5, SHA1) 대신 PBKDF2, bcrypt, scrypt, Argon2와 같이 강력한 솔티드(salted) 해시 함수를 사용하여 비밀번호를 저장합니다.
- 민감한 데이터를 포함하는 캐시를 비활성화하고, 웹 서버의 캐시 설정이 안전한지 확인합니다.
- 에러 메시지나 개발자 콘솔 등에서 민감한 정보가 노출되지 않도록 주의합니다.
Attack Scenarios
Scenario #1: 평문으로 저장된 신용카드 정보 유출 온라인 쇼핑몰 데이터베이스에 고객의 신용카드 정보가 암호화되지 않은 평문 상태로 저장되어 있습니다. 공격자가 SQL 인젝션 취약점을 통해 데이터베이스에 접근하면, 고객의 모든 신용카드 정보를 쉽게 탈취하여 금융 사기에 악용할 수 있습니다.
Scenario #2: HTTP를 통한 민감 데이터 전송 및 중간자 공격 사용자가 HTTP (HTTPS가 아닌)를 통해 민감한 개인 정보나 로그인 자격 증명을 전송하는 웹사이트에 접속합니다. 공격자가 중간자(Man-in-the-Middle) 공격을 수행하면, 전송되는 평문 데이터를 가로채서 사용자의 계정을 탈취하거나 개인 정보를 수집할 수 있습니다.
Scenario #3: 약하게 해싱된 비밀번호의 복호화 애플리케이션이 사용자 비밀번호를 솔트 없이 MD5로 해싱하여 데이터베이스에 저장합니다. 공격자가 데이터베이스에 접근하여 해싱된 비밀번호를 탈취한 후, 레인보우 테이블(Rainbow Table) 또는 무차별 대입 공격(Brute-force Attack)을 통해 원본 비밀번호를 쉽게 복호화할 수 있습니다.
A4:XML External Entities (XXE)
Description
XML 외부 엔티티(XML External Entities, XXE) 취약점은 많은 오래되거나 제대로 구성되지 않은 XML 프로세서가 XML 문서 내의 외부 엔티티 참조를 처리할 때 발생합니다. 외부 엔티티는 file URI
핸들러를 사용하여 내부 파일을 공개하거나, 내부 파일 공유에 접근하거나, 내부 포트 스캐닝을 수행하거나, 원격 코드 실행 및 서비스 거부 공격을 수행하는 데 악용될 수 있습니다.
- 애플리케이션이 직접 XML을 입력 받거나, 특히 신뢰할 수 없는 출처로부터 XML을 업로드하거나 데이터를 입력할 경우 취약할 수 있습니다.
- XXE 공격에 취약하다는 것은 Billion Laughs 공격(XML Bomb)을 포함하는 서비스 거부(DoS) 공격에 취약하다는 것을 의미합니다. 이 공격은 수많은 중첩된 엔티티 정의를 사용하여 XML 파서의 메모리를 고갈시켜 서비스를 마비시킵니다.
Prevention
XXE 공격을 예방하기 위한 핵심은 XML 파서의 외부 엔티티 처리 기능을 비활성화하는 것입니다.
- JSON과 같은 덜 복잡한 데이터 형식을 사용하거나, 민감한 데이터 사용을 지양합니다. 가능한 경우 XML 대신 다른 데이터 교환 형식을 고려합니다.
- XML 프로세서와 라이브러리를 최신 버전으로 패치하거나 업그레이드합니다. 최신 버전은 XXE 공격에 대한 방어 기능을 기본적으로 제공하거나 쉽게 구성할 수 있습니다.
- SOAP(XML 기반 메시징 프로토콜)를 사용하는 경우, SOAP 1.2 이상으로 업그레이드합니다.
- 서버에서 필터링 및 검사를 사용하여 XML 문서, 헤더, 노드에 있는 악의적인 데이터를 막습니다. 이는 입력 유효성 검사 강화의 일환입니다.
- XML 파일 업로드 시에는 XSD(XML Schema Definition) 검증기 등을 사용하여 업로드되는 XML 문서의 구조와 내용을 사전에 정의된 스키마에 따라 유효성 검사합니다.
- 모든 DTD(Document Type Definition) 처리를 비활성화하는 것이 가장 효과적인 방법입니다. 대부분의 XML 파서는 외부 엔티티를 포함하여 DTD 기능을 비활성화하는 옵션을 제공합니다.
Attack Scenarios
Scenario #1: 내부 파일 접근 및 정보 유출 애플리케이션이 사용자로부터 XML 파일을 입력받아 파싱합니다. 공격자는 XML 문서 내에
<!ENTITY xxe SYSTEM "file:///etc/passwd">
와 같은 외부 엔티티를 정의하고, 이 엔티티를 문서 내에서 참조합니다. XML 파서가 이 외부 엔티티를 처리하게 되면,/etc/passwd
파일의 내용이 애플리케이션의 응답에 포함되어 공격자에게 노출됩니다. 이는 시스템의 사용자 정보나 다른 민감한 파일의 유출로 이어질 수 있습니다.Scenario #2: 서비스 거부(Denial of Service) 공격 (Billion Laughs Attack) 공격자는 중첩된 외부 엔티티를 사용하여 작은 크기의 XML 문서가 파싱될 때 엄청난 양의 메모리를 소비하도록 만듭니다. 예를 들어,
&lol9;
와 같이 수많은 엔티티가 서로를 참조하게 하여 XML 파서가 과도한 리소스를 할당하게 만들어 서버가 응답 불능 상태에 빠지게 합니다.
A5:Broken Access Control
Description
접근 통제 깨짐(Broken Access Control)은 인증된 사용자가 수행할 수 있는 작업에 대한 제한이 제대로 강제되지 않을 때 자주 발생합니다. 공격자는 이러한 결함을 악용하여 인가되지 않은 기능 및/또는 데이터에 접근할 수 있습니다. 예를 들어, 다른 사용자의 계정에 접근하거나, 민감한 파일을 보거나, 다른 사용자의 데이터를 수정하거나, 접근 권한을 변경하는 등의 행위를 할 수 있습니다.
- 다른 계정의 정보를 열람하거나 편집할 수 있다면 이러한 취약점이 존재하는 것입니다.
- JWT(JSON Web Token) 토큰의 재전송(replaying) 또는 변경(tampering)이 허용된다면 접근 통제에 실패한 것입니다.
- 인가되지 않은 API에 접근을 허용하는 것도 취약점 중 하나입니다. 예를 들어, 일반 사용자 역할로 API를 호출하여 관리자 전용 기능을 실행할 수 있는 경우입니다.
- 기본적으로 ‘허용(allow)’ 정책이 설정되어 있어, 명시적으로 ‘거부(deny)’ 규칙을 설정하지 않으면 모든 접근을 허용하는 경우가 있습니다.
Prevention
접근 통제는 공격자가 접근 통제 검사나 메타데이터를 수정할 수 없는 신뢰할 수 있는 서버 측 코드 또는 서버리스(server-less) API에서만 효과적으로 적용되어야 합니다.
- 기본 정책으로 ‘차단(deny)’을 해야 합니다. 즉, 명시적으로 허용된 경우를 제외하고는 모든 접근을 거부하는
deny-by-default
원칙을 적용합니다. - 접근 통제 모델은 사용자에게 특정 레코드를 생성/열람/수정/삭제할 수 있는 권한을 허용하기보다, 레코드 소유자만 권한을 갖게끔 강제 설정해야 합니다. 이는 수평적 권한 상승(Horizontal Privilege Escalation)을 방지하는 데 중요합니다.
- 웹 서버상의 디렉토리 리스팅 기능을 비활성화하고,
.git
과 같은 메타데이터 파일이나 백업 파일들이 웹 루트(web root)에 존재하지 않도록 운영해야 합니다. - JWT는 로그아웃 이후 즉시 무효화되어야 하며, 짧은 유효 기간을 설정하는 것이 좋습니다.
- 모든 접근 통제 결정은 서버 측에서 이루어져야 하며, 클라이언트 측에서 이루어지는 접근 통제는 쉽게 우회될 수 있습니다.
- 접근 통제 실패에 대한 적절한 로깅 및 모니터링을 구현하여 의심스러운 활동을 신속하게 감지하고 대응합니다.
Attack Scenarios
Scenario #1: URL 조작을 통한 수평적 권한 상승 사용자가
https://example.com/profile?id=123
과 같이 자신의 프로필을 볼 수 있는 URL에 접근합니다. 공격자는id
값을124
로 변경하여https://example.com/profile?id=124
로 요청을 보냅니다. 만약 애플리케이션이 사용자의 ID가 요청된 프로필 ID와 일치하는지 제대로 검증하지 않는다면, 공격자는 다른 사용자의 프로필 정보를 열람하거나 수정할 수 있게 됩니다.Scenario #2: API 엔드포인트에 대한 접근 통제 부족 애플리케이션에
GET /api/v1/users
와 같이 모든 사용자 목록을 반환하는 API 엔드포인트가 있습니다. 이 API는 원래 관리자만 접근할 수 있도록 설계되었지만, 서버 측에서 사용자 역할(role)에 대한 인가(authorization) 검증이 누락되어 일반 사용자도 이 API를 호출할 수 있습니다. 공격자는 이 API를 호출하여 시스템의 모든 사용자 정보를 탈취할 수 있습니다.Scenario #3:
HTTP Method
변조를 통한 접근 우회 사용자가 자신만 삭제할 수 있는 게시물에 대해GET /post/delete?id=123
요청을 보냅니다. 서버는GET
요청이라 삭제를 허용하지 않습니다. 하지만 공격자는 이 요청을POST
요청으로 변경하여 보냅니다. 만약 서버가POST
요청에 대한 접근 통제를 제대로 구현하지 않았다면, 공격자는 자신이 소유하지 않은 게시물도 삭제할 수 있게 됩니다.
A6:Security Misconfiguration
Description
보안 설정 오류(Security Misconfiguration)는 가장 흔하게 발견되는 보안 문제 중 하나입니다. 이는 주로 안전하지 않은 기본 설정, 불완전하거나 임시적인 설정, 공개된 클라우드 저장소, 잘못 구성된 HTTP 헤더, 그리고 민감한 정보를 포함하는 상세한 에러 메시지 등으로 인해 발생합니다. 모든 운영 체제, 프레임워크, 라이브러리, 그리고 애플리케이션은 안전하게 구성되어야 할 뿐만 아니라, 적시에 패치/업그레이드되어야 합니다.
- 기본 계정과 비밀번호가 활성화되어 있거나 해당 정보들을 변경 없이 사용하고 있으면 취약한 상태입니다.
- 에러 처리 과정에서 스택 추적 정보나 공격에 도움이 될 만한 다른 정보들(예: 컴포넌트 버전, 내부 경로)을 노출하고 있어도 위험합니다.
- 서버, 프레임워크, 라이브러리, 데이터베이스 상에 보안 설정이 되어 있지 않거나 구버전을 사용해도 이 취약점에 해당됩니다.
- 사용하지 않는 불필요한 기능, 서비스, 포트 등이 활성화되어 있는 경우 잠재적인 공격 표면(attack surface)을 증가시킵니다.
- 웹 서버나 애플리케이션 서버에서 보안 헤더(Security Headers)가 제대로 설정되지 않거나 누락된 경우 (예:
Content-Security-Policy
,X-Content-Type-Options
,X-Frame-Options
등)
Prevention
보안 설정 오류를 방지하기 위해서는 일관되고 반복 가능한 보안 구성 프로세스를 구축하는 것이 중요합니다.
- 불필요한 기능, 구성 요소를 제거하여 최소한의 플랫폼을 유지하고, 사용하지 않는 기능과 프레임워크는 삭제하거나 설치하지 말아야 합니다.
- 모든 보안 정보, 업데이트, 패치를 대상으로 적절한 검토와 갱신 절차가 필요합니다. 이는 정기적인 취약점 스캔 및 보안 감사 프로세스에 포함되어야 합니다.
- 세분화(segmentation), 컨테이너화(containerization), 클라우드 보안 그룹과 같은 방법으로 효율적이고 안전한 격리(isolation)를 제공하는 아키텍처를 적용해야 합니다.
- 모든 환경(개발, 테스트, 운영)에서 보안 설정이 적절히 반영되어 있는지 검증할 수 있는 자동화된 절차를 수립해야 합니다. 이를 통해 배포 과정에서 발생할 수 있는 설정 오류를 최소화합니다.
- 기본 계정의 비밀번호는 반드시 변경하고, 강력한 비밀번호 정책을 강제해야 합니다.
- 에러 메시지는 일반적인 정보만을 제공하고, 스택 추적이나 내부 시스템 정보 등 민감한 내용은 사용자에게 노출하지 않아야 합니다.
Attack Scenarios
Scenario #1: 웹 서버 디렉토리 리스팅 허용 웹 서버의 설정 오류로 디렉토리 리스팅 기능이 활성화되어 있습니다. 공격자는 웹 브라우저를 통해
/backup
이나/temp
와 같은 디렉토리에 접근하여, 개발자가 실수로 업로드한 백업 파일(.bak
,.zip
)이나 설정 파일(.config
,.env
)을 발견할 수 있습니다. 이 파일들에는 데이터베이스 연결 정보, API 키 등 민감한 자격 증명이 포함되어 있을 수 있으며, 이를 통해 공격자는 시스템에 더 깊이 침투할 수 있습니다.Scenario #2: 개발용/샘플 애플리케이션의 프로덕션 환경 잔존 프로덕션 서버에 제거되지 않은 개발용 샘플 애플리케이션이나 관리 콘솔이 그대로 배포되어 있습니다. 이 샘플 애플리케이션은 기본 비밀번호를 사용하고 있거나, 알려진 보안 취약점을 포함하고 있을 수 있습니다. 공격자는 이 취약점을 악용하거나 기본 비밀번호로 접근하여 서버를 장악할 수 있습니다.
Scenario #3: 클라우드 스토리지 버킷의 Public 접근 클라우드 서비스(예: AWS S3)에 데이터를 저장하는 애플리케이션에서, 스토리지 버킷의 접근 권한이 Public Read/Write로 잘못 설정되어 있습니다. 공격자는 이 설정 오류를 이용하여 버킷에 저장된 모든 민감한 데이터를 열람하거나, 악성 파일을 업로드하여 웹사이트 변조나 악성코드 배포에 사용할 수 있습니다.
A7:Cross-Site Scripting (XSS)
Description
크로스-사이트 스크립팅(XSS) 취약점은 애플리케이션이 신뢰할 수 없는 데이터를 새로운 웹 페이지에 적절한 유효성 검사나 이스케이프(escaping) 없이 포함하거나, HTML 또는 JavaScript를 생성할 수 있는 브라우저 API를 사용하여 사용자 제공 데이터로 기존 웹 페이지를 업데이트할 때 발생합니다. XSS는 공격자가 피해자의 브라우저에서 스크립트를 실행할 수 있도록 허용하며, 이는 사용자 세션 하이재킹, 웹사이트 변조, 또는 사용자를 악성 사이트로 리다이렉션하는 등의 피해로 이어질 수 있습니다.
- 일반적으로 세 가지 주요 XSS 유형이 있습니다:
- Reflected XSS (반사 XSS): 공격자의 스크립트가 HTTP 요청에 포함되어 서버를 통해 사용자에게 즉시 “반사”되어 실행됩니다. (예: 검색 결과 페이지에 악성 스크립트가 포함되어 표시되는 경우)
- Stored XSS (저장 XSS 또는 지속 XSS): 공격자의 스크립트가 데이터베이스와 같은 서버 측 저장소에 저장된 후, 나중에 다른 사용자에게 제공될 때 실행됩니다. (예: 게시판 게시글, 댓글, 프로필 정보에 악성 스크립트를 삽입하여 저장하고, 다른 사용자가 해당 페이지를 볼 때 스크립트가 실행되는 경우)
- DOM-based XSS (DOM 기반 XSS): 서버를 거치지 않고, 웹 페이지의 클라이언트 측 스크립트가 DOM(Document Object Model)을 조작하여 사용자 입력값을 안전하지 않게 처리할 때 발생합니다. (예: 클라이언트 측 JavaScript가 URL 해시(#) 값을 사용하여 페이지 내용을 동적으로 생성하는데, 이 값에 악성 스크립트가 포함되는 경우)
Prevention
XSS 공격을 방어하는 핵심은 사용자 입력을 신뢰하지 않고, 출력될 때 컨텍스트에 맞게 적절히 처리하는 것입니다.
- 모든 사용자 입력에 대해 적절한 유효성 검사 및 이스케이프를 수행해야 합니다. 특히 HTML 컨텍스트, JavaScript 컨텍스트, URL 컨텍스트 등 출력되는 컨텍스트에 맞춰 이스케이프를 적용해야 합니다.
- HTML 엔티티 인코딩: 사용자 입력이 HTML 콘텐츠로 출력될 때,
&
,<
,>
,"
,'
,/
와 같은 특수 문자를 HTML 엔티티로 변환하여 브라우저가 스크립트로 해석하지 못하게 합니다.
- HTML 엔티티 인코딩: 사용자 입력이 HTML 콘텐츠로 출력될 때,
- 콘텐츠 보안 정책(Content Security Policy, CSP)을 구현: CSP는 웹 애플리케이션이 로드할 수 있는 리소스(스크립트, 스타일시트, 이미지 등)의 출처를 제한하여 XSS 및 다른 유형의 콘텐츠 인젝션 공격을 완화하는 데 도움을 줍니다.
- 안전하지 않은 JavaScript API 사용을 피합니다. (예:
innerHTML
,document.write()
,eval()
). 대신textContent
,appendChild()
와 같이 텍스트 콘텐츠만을 다루는 안전한 API를 사용합니다. - HTTPOnly 속성을 사용하여 쿠키를 보호:
HTTPOnly
플래그가 설정된 쿠키는 JavaScript를 통해 접근할 수 없으므로, XSS 공격으로 인한 세션 쿠키 탈취를 방지할 수 있습니다. - 입력 유효성 검사: 클라이언트 측과 서버 측 모두에서 사용자 입력에 대한 유효성 검사를 수행하여 악의적인 데이터가 시스템에 유입되는 것을 최소화합니다.
Attack Scenarios
Scenario #1: 검색 결과 페이지를 통한 Reflected XSS 사용자가 웹사이트 검색창에
"><script>alert('XSS Attack');</script>
와 같은 악성 스크립트를 입력합니다. 웹사이트는 이 입력값을 제대로 이스케이프하지 않고 검색 결과 페이지에 그대로 반영합니다. 이로 인해 페이지를 방문하는 다른 사용자들의 브라우저에서alert('XSS Attack')
스크립트가 실행되고, 이는 세션 쿠키 탈취나 악성 사이트 리다이렉션으로 이어질 수 있습니다.Scenario #2: 게시판 댓글을 통한 Stored XSS 공격자가 게시판 댓글 작성 시
<h1>Malicious Comment <script>fetch('/api/steal_cookie', {method: 'POST', body: document.cookie});</script></h1>
와 같은 악성 스크립트를 포함한 댓글을 작성합니다. 이 댓글이 데이터베이스에 저장되고, 다른 사용자가 해당 게시물을 열람할 때마다 브라우저에서 스크립트가 실행되어 사용자 세션 쿠키가 공격자 서버로 전송됩니다. 공격자는 탈취한 쿠키로 사용자의 세션을 하이재킹하여 계정을 도용할 수 있습니다.Scenario #3: 클라이언트 측 DOM 기반 XSS 웹 페이지의 JavaScript 코드가 URL의
#
(해시) 값에서 데이터를 읽어와document.write()
를 사용하여 페이지에 동적으로 내용을 추가합니다. 공격자는 악성 URLhttp://example.com/page.html#<script>alert('XSS');</script>
를 사용자에게 전달합니다. 사용자가 이 URL을 클릭하면, 클라이언트 측 JavaScript가#
값에 포함된 스크립트를 실행하여 XSS 공격이 발생합니다.
A8:Insecure Deserialization
Description
안전하지 않은 역직렬화(Insecure Deserialization)는 직렬화된 객체를 안전하지 않게 역직렬화할 때 발생하는 취약점입니다. 이는 종종 원격 코드 실행(Remote Code Execution, RCE)으로 이어질 수 있으며, RCE로 이어지지 않더라도 재생 공격(replay attacks), 인젝션 공격, 그리고 권한 상승 공격을 포함한 다양한 공격에 사용될 수 있습니다.
- 이 공격은 결코 쉽지 않으며, 개발자가 직렬화/역직렬화의 보안적 함의를 제대로 이해하지 못할 때 발생합니다.
- 직렬화(Serialization)는 데이터를 저장하거나 네트워크를 통해 전송하기 위해 객체를 일련의 바이트 스트림으로 변환하는 과정입니다. 역직렬화(Deserialization)는 그 반대로 바이트 스트림을 다시 객체로 변환하는 과정입니다.
- 만약
user
권한을 주는 직렬화된 데이터가 전송될 때, 공격자가 이를 변조하여 역직렬화하는 과정에서admin
권한으로 변조해버리면 치명적인 문제가 발생할 수 있습니다. 이는 역직렬화 과정에서 신뢰할 수 없는 데이터가 코드로 해석되어 실행될 수 있기 때문입니다.
Prevention
안전하지 않은 역직렬화 공격을 방어하기 위한 가장 강력한 방법은 신뢰할 수 없는 소스로부터 직렬화된 객체를 역직렬화하지 않는 것입니다.
- 신뢰할 수 없는 출처로부터 직렬화된 객체를 허용하지 않습니다. 이는 가장 효과적인 방어책입니다.
- 직렬화된 데이터의 디지털 서명(digital signatures)이나 무결성 검사(integrity checks)와 같은 것을 구현하여 데이터 변조를 탐지합니다. 서명이 유효하지 않거나 데이터가 손상된 경우 역직렬화를 거부합니다.
- 역직렬화하는 과정에서 역직렬화될 수 있는 클래스에 제약을 두는 것이 좋습니다. (예: 화이트리스트 기반의 클래스 필터링) 하지만 이것은 우회 방법이 존재할 수 있으므로 완벽한 방어책은 아닙니다.
- 역직렬화하는 과정을 모니터링하고, 비정상적인 역직렬화 시도가 지속적으로 발생할 경우 경고합니다.
- 보안적인 직렬화/역직렬화 라이브러리를 사용하고, 개발자가 안전하지 않은 기능을 사용하지 않도록 교육합니다.
- 객체 그래프에 원격 코드 실행을 허용하는 클래스(예:
Runtime.exec()
,ProcessBuilder
)가 포함되지 않도록 확인합니다.
Attack Scenarios
Scenario #1: Java 역직렬화를 통한 원격 코드 실행 Java 애플리케이션이
ObjectInputStream.readObject()
를 사용하여 사용자로부터 전송된 직렬화된 객체를 역직렬화합니다. 공격자는 Apache Commons Collections 라이브러리의 알려진 역직렬화 취약점을 이용하여, 악의적인 페이로드(payload)를 포함하는 직렬화된 객체를 생성하여 애플리케이션에 전송합니다. 애플리케이션이 이 객체를 역직렬화하는 과정에서, 공격자가 의도한 임의의 명령어가 서버에서 실행되어 서버가 장악될 수 있습니다.Scenario #2: .NET 역직렬화를 통한 권한 상승 .NET 애플리케이션이
BinaryFormatter
를 사용하여 직렬화된 데이터를 처리합니다. 공격자는 관리자 권한을 가진 사용자 객체를 직렬화하고 이를 변조하여 애플리케이션에 전송합니다. 애플리케이션이 이 객체를 역직렬화할 때, 공격자는 일반 사용자 권한에서 관리자 권한으로 권한을 상승시켜 민감한 기능에 접근할 수 있게 됩니다.
A9:Using Components with Known Vulnerabilities
Description
알려진 취약점이 있는 컴포넌트 사용(Using Components with Known Vulnerabilities)은 애플리케이션이 사용하는 라이브러리, 프레임워크, 그리고 다른 소프트웨어 모듈과 같은 컴포넌트에 알려진 보안 취약점이 있음에도 불구하고, 이를 업데이트하거나 적절히 패치하지 않을 때 발생합니다. 이러한 컴포넌트들은 애플리케이션과 동일한 권한으로 실행됩니다. 따라서 취약한 컴포넌트가 악용된 경우, 심각한 데이터 손실을 일으키거나 서버가 장악될 수 있습니다. 알려진 취약점을 가진 컴포넌트를 사용하는 애플리케이션 및 API는 애플리케이션의 방어 체계를 약화시키고 다양한 공격 및 영향에 노출될 수 있습니다.
- 소프트웨어가 취약하거나, 더 이상 지원되지 않거나(End-of-Life), 오래된 버전일 경우 취약할 가능성이 매우 높습니다.
- 새로 업그레이드된 라이브러리의 호환성을 테스트하지 않아 업데이트를 꺼리게 되고, 결국 취약한 버전을 계속 사용하게 되는 경우가 많습니다.
- 라이브러리, 프레임워크 및 다른 소프트웨어 모듈과 같은 컴포넌트가 애플리케이션과 같은 권한으로 실행되기 때문에, 이들 중 하나라도 취약점이 있다면 애플리케이션 전체에 심각한 영향을 미칠 수 있습니다.
Prevention
알려진 취약점을 가진 컴포넌트의 사용을 방지하기 위해서는 지속적인 모니터링과 체계적인 관리 프로세스가 필수적입니다.
- 사용하지 않는 구성 요소는 제거하고, 플랫폼을 최소한으로 유지합니다. 불필요한 의존성을 줄이는 것이 중요합니다.
- 안전한 출처(Official Source)에서 컴포넌트를 다운로드하고, 패키지의 무결성을 확인(예: 해시 값 검증, 디지털 서명 검증)하여 악성 코드가 삽입되지 않았는지 확인합니다.
- CVE(Common Vulnerabilities and Exposures), NVD(National Vulnerability Database)와 같은 취약점 데이터베이스를 지속적으로 모니터링하고, 자신이 사용하고 있는 컴포넌트에 대한 새로운 보안 취약점 뉴스를 구독하여 즉시 대응할 수 있도록 합니다.
- 소프트웨어 구성 분석(Software Composition Analysis, SCA) 도구를 사용하여 오픈 소스 및 써드파티 라이브러리의 알려진 취약점을 식별하고 관리합니다.
- 패치가 불가능하거나 현실적으로 적용하기 어려운 경우, 가상 패치(Virtual Patching)와 같은 완화 전략을 고려해야 합니다. 이는 웹 방화벽(WAF) 등을 통해 취약점 공격 패턴을 차단하는 방식입니다.
- 모든 조직은 애플리케이션의 수명 주기 동안 지속적인 모니터링, 업데이트 확인 및 구성 변경을 수행해야 합니다. IoT 기기나 생체 의료 장비와 같이 주기적인 패치가 어렵거나 불가능한 환경이라도, 보안 패치를 적용하는 것이 중요할 수 있습니다.
Attack Scenarios
Scenario #1: 오래된 웹 서버 라이브러리 취약점 악용 애플리케이션이 오래된 버전의 Apache Struts 프레임워크를 사용하고 있습니다. 이 버전에는 원격 코드 실행(RCE) 취약점이 알려져 있습니다. 공격자는 이 취약점을 악용하여 악성 HTTP 요청을 웹 서버에 보내고, 이를 통해 서버에서 임의의 코드를 실행시킬 수 있습니다. 결과적으로 공격자는 서버를 완전히 장악하고, 민감한 데이터를 탈취하거나 웹사이트를 변조할 수 있습니다.
Scenario #2: npm 패키지 내 악성 코드 개발자가 웹 애플리케이션에 사용하기 위해 npm 레지스트리에서 인기 있는 JavaScript 라이브러리를 다운로드하여 프로젝트에 포함시킵니다. 하지만 이 라이브러리의 특정 버전에는 공격자가 삽입한 백도어(backdoor)가 포함되어 있습니다. 개발자는 이 사실을 모른 채 애플리케이션을 배포하고, 백도어는 사용자들의 민감한 정보를 외부 서버로 전송하는 데 사용됩니다. 이는 컴포넌트의 출처를 제대로 검증하지 않았기 때문에 발생합니다.
Scenario #3: CMS 플러그인 취약점을 통한 웹사이트 변조 워드프레스와 같은 CMS(콘텐츠 관리 시스템)를 사용하는 웹사이트에서, 설치된 플러그인 중 하나가 최신 보안 패치를 적용하지 않은 오래된 버전을 사용하고 있습니다. 이 플러그인에 파일 업로드 취약점이 존재하며, 공격자는 이를 악용하여 웹 셸(web shell)을 업로드하고 웹사이트를 변조하거나 악성 코드를 삽포하는 데 사용합니다.
A10:Insufficient Logging & Monitoring
Description
불충분한 로깅 및 모니터링(Insufficient Logging & Monitoring)은 부족한 로깅과 모니터링이 사고 대응(incident response)과의 비효율적인 통합과 결합될 때 발생합니다. 이는 공격자들이 시스템을 더욱 공격하고, 지속성(persistence)을 유지하며, 더 많은 시스템으로 확장하고, 데이터를 변조, 추출 또는 파괴하도록 허용합니다. 대부분의 침해 연구에 따르면, 침해를 탐지하는 데 걸리는 시간은 평균 200일 이상이며, 주로 내부 프로세스나 모니터링이 아닌 외부 당사자(예: 고객, 규제 기관)에 의해 탐지됩니다.
- 불충분한 로깅과 모니터링은 모든 중요한 보안 사고의 기반이 됩니다. 이러한 취약점으로 인해 공격자들은 탐지되지 않고 시스템에 더 오래 머무르며 더 큰 피해를 입힐 수 있습니다.
- 불필요한 로그를 많이 남기는 것도 좋지 않지만, 감시해야 할 이벤트들(예: 로그인 시도, 접근 통제 실패, 중요한 데이터 변경, 관리자 활동)은 반드시 기록해야 합니다.
- 로그인 및 로그인 실패와 같은 중요한 활동에 대한 로그가 모니터링 되지 않거나, 경고 및 오류에 대한 로그 메시지가 없거나, 의심스러운 활동에 대한 API 호출 로그를 모니터링하지 않으면 이러한 취약점에 노출될 수 있습니다.
- 로그를 단지 로컬에만 저장하고, 사용자나 공격자에게 로깅이나 경고 이벤트가 보여질 수 있다면 (예: 웹 페이지에 상세한 에러 로그가 그대로 노출) 이러한 취약점을 가지고 있는 것입니다. 이는 공격자에게 유용한 시스템 정보를 제공합니다.
Prevention
불충분한 로깅 및 모니터링 취약점을 방어하기 위해서는 체계적인 로깅, 중앙 집중식 모니터링, 그리고 신속한 사고 대응 프로세스를 구축해야 합니다.
- 모든 로그인, 접근 통제 실패, 서버 측 입력값 검증 실패 등 의심스럽거나 악의적인 계정 활동을 식별할 수 있는 내용들은 로깅해야 합니다.
- 중앙 집중식 로그 관리 솔루션(예: SIEM, Splunk, ELK Stack)에 의해 쉽게 사용될 수 있는 형식으로 로그가 생성되는지 확인하여 보안 대책을 세웁니다. 이는 로그를 효율적으로 수집, 저장, 분석할 수 있도록 합니다.
- 로그는 충분한 컨텍스트(context) 정보를 포함해야 합니다. (예: 타임스탬프, 사용자 ID, 소스 IP 주소, 요청된 URL, 작업 유형, 결과 등)
- 로그 무결성을 보호해야 합니다. 공격자가 로그를 변조하거나 삭제하지 못하도록 합니다. (예: WORM(Write Once Read Many) 저장소, 로그 전송 시 암호화 및 무결성 검증, 로그 서버 접근 제어)
- 실시간에 가까운 모니터링 및 경고 시스템을 구축하여 의심스러운 활동이 발생했을 때 즉시 알림을 받을 수 있도록 합니다. (예: 임계값 기반 알림, 비정상 행위 감지)
- 로그 데이터를 정기적으로 분석하여 패턴을 파악하고, 비정상적인 활동을 식별합니다.
- 사고 대응 계획(Incident Response Plan)을 수립하고, 로깅 및 모니터링 시스템을 이 계획에 통합하여 침해 발생 시 신속하게 탐지하고 대응할 수 있도록 합니다.
Attack Scenarios
Scenario #1: 탐지되지 않는 지속적인 데이터 유출 공격자가 SQL 인젝션 취약점을 통해 데이터베이스에 접근하여 민감한 정보를 지속적으로 추출합니다. 하지만 애플리케이션 서버의 로그에는 비정상적인 데이터베이스 쿼리나 대량의 데이터 전송에 대한 기록이 없거나, 관련 경고 시스템이 설정되어 있지 않습니다. 이로 인해 공격자는 수개월 동안 탐지되지 않은 채 데이터를 계속해서 유출할 수 있으며, 기업은 막대한 피해를 입게 됩니다.
Scenario #2: 에러 메시지를 통한 시스템 정보 노출 및 공격 발판 마련 애플리케이션 서버가 사용자에게 상세한 에러 메시지(예: 스택 트레이스, 데이터베이스 연결 정보, 내부 IP 주소)를 노출합니다. 이 에러 메시지는 서버의 취약한 컴포넌트 버전이나 내부 네트워크 구조에 대한 힌트를 제공합니다. 충분한 로깅 및 모니터링이 없어 이러한 정보 노출이 감지되지 않으면, 공격자는 이 정보를 활용하여 다음 공격 단계를 계획하고 실행할 수 있습니다.
Scenario #3: 로그인 실패 모니터링 부족으로 인한 크리덴셜 스터핑 성공 대규모 크리덴셜 스터핑 공격이 애플리케이션의 로그인 페이지에서 발생합니다. 수만 건의 로그인 시도가 짧은 시간 내에 이루어지지만, 로그인 실패 횟수에 대한 로깅이나 임계값 기반 모니터링이 없어 이러한 비정상적인 활동이 감지되지 않습니다. 결국 공격자는 일부 계정에 성공적으로 로그인하고 세션을 탈취하지만, 시스템 관리자는 침해 사실을 인지하지 못하고 피해가 확산됩니다.