Total Pageviews

Showing posts with label Fortify. Show all posts
Showing posts with label Fortify. Show all posts

2018/02/14

[Fortify] Fix Cross-Site Scripting: Persistent

Problem


Before
Code snippet in JSP file:
1
2
    String content = report.getContent();
    out.print(content);


After

Add dependency in pom.xml
1
2
3
4
5
    <dependency>
        <groupId>org.owasp.encoder</groupId>
        <artifactId>encoder</artifactId>
        <version>1.2.1</version>
    </dependency>

Updated code snippet in JSP file:
1
2
3
4
5
    <%@ page import="org.owasp.encoder.Encode"%>


    String content = report.getContent(acct_no,schema+"://"+server+":"+port);
    out.print(Encode.forHtml(content));    


Reference
[1] https://github.com/OWASP/owasp-java-encoder/wiki/2)-Use-the-OWASP-Java-Encoder

2018/01/05

[Fortify] Fix Unreleased Resource: Database

Before
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.dbutils.QueryRunner;

public class DaoBase {

    public Connection getConnection() throws SQLException {
        return MyDataSource.getInstance().getDatasource().getConnection();
    }

    public List<Map<String, Object>> find(String sql) throws SQLException {
        List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();

        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            con = getConnection();
            stmt = con.createStatement();
            rs = stmt.executeQuery(sql);

            // ...
        } catch (SQLException e) {
            throw e;
        } finally {
            if(rs != null) {
                rs.close();
            }
            if(stmt != null) {
                stmt.close();
            }
            if(con != null) {
                con.close();
            }
        }

        return datas;
    }
}



After
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.dbutils.QueryRunner;

public class DaoBase {

    public Connection getConnection() throws SQLException {
        return MyDataSource.getInstance().getDatasource().getConnection();
    }

    public List<Map<String, Object>> find(String sql) throws SQLException {
        List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();

        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            con = getConnection();
            stmt = con.createStatement();
            rs = stmt.executeQuery(sql);

            // ignore...
        } catch (SQLException e) {
            throw e;
        } finally {
            close(rs);
            close(stmt);
            close(con);
        }

        return datas;
    }

    public void close(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
            }
        }
    }

    public void close(Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
            }
        }
    }

    public void close(Connection con)  {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
            }
        }
    }
}




2018/01/04

[Fortify] Fix SQL Injection

Before

code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    public List<AccountDtl> getAcctDetail(List<String> acctNos) throws SQLException {

        List<AccountDtl> result = new ArrayList<AccountDtl>();

        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;

        String accounts = "";
        for (String account : acctNos) {
            accounts = accounts + "'" + account + "',";
        }
        
        String sql = "select DISTINCT ( TRIM(REC_ID))  , NO , ID from " + Table.test.getFullName()
                + " where acct_no in (" + accounts.substring(0, accounts.length() - 1) + ")";
        
        try {
            conn = getConnection();
            pst = conn.prepareStatement(sql);
            rs = pst.executeQuery();
            // ignore code snippet regarding get values 
        } catch (SQLException e) {
            throw e;
        } finally {
            close(rs);
            close(pst);
            close(conn);
        }

        return result;
    }


After


Add dependency to your pom.xml
1
2
3
4
5
    <dependency>
        <groupId>org.owasp.esapi</groupId>
        <artifactId>esapi</artifactId>
        <version>2.1.0</version>
    </dependency>



Updated code snippet (If you are not using DB2 as your database, please apply other Codec, ex. OracleCodec):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
     import org.owasp.esapi.ESAPI;
     import org.owasp.esapi.codecs.DB2Codec;

     // ignore code snippet
     
     public List<AccountDtl> getAcctDetail(List<String> acctNos) throws SQLException {

        List<AccountDtl> result = new ArrayList<AccountDtl>();

        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;

        String accounts = "";
        for (String account : acctNos) {
            accounts = accounts + "'" + ESAPI.encoder().encodeForSQL(new DB2Codec(), account) + "',";
        }
        
        String sql = "select DISTINCT ( TRIM(REC_ID))  , NO , ID from " + Table.test.getFullName()
                + " where acct_no in (" + accounts.substring(0, accounts.length() - 1) + ")";
        
        try {
            conn = getConnection();
            pst = conn.prepareStatement(sql);
            rs = pst.executeQuery();
            // ignore code snippet regarding get values 
        } catch (SQLException e) {
            throw e;
        } finally {
            close(rs);
            close(pst);
            close(conn);
        }

        return result;
    }



2017/12/11

[Fortify] Fix Path Manipulation

Problem


Before
Original code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    public static List<String> readFile(String file) throws TdccInitException, IOException {
        List<String> rows = new ArrayList<>();

        if (!StringUtils.isNotEmpty(file)) {
            throw new TdccInitException("Please assign file, must not be empty or null");
        }
        Boolean isFileExisted = Files.exists(Paths.get(file));
        if (!isFileExisted) {
            throw new TdccInitException(MessageFormat.format(wrongFileErr, file));
        } else {
            rows = com.google.common.io.Files.readLines(new File(file), Charsets.UTF_8);
        }
        return rows;
    }


After
Add dependency in your pom.xml
1
2
3
4
5
6
    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>


Updated code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    public static List<String> readFile(String file) throws TdccInitException, IOException {
        List<String> rows = new ArrayList<>();

        if (!StringUtils.isNotEmpty(file)) {
            throw new TdccInitException("Please assign file, must not be empty or null");
        }
        file = FilenameUtils.normalize(file);
        Boolean isFileExisted = Files.exists(Paths.get(file));
        if (!isFileExisted) {
            throw new TdccInitException(MessageFormat.format(wrongFileErr, file));
        } else {
            rows = com.google.common.io.Files.readLines(new File(file), Charsets.UTF_8);
        }
        return rows;
    }



2017/11/11

[Fortify] Fix Locale Dependent Comparison

Problem


Before
The original code snippet is the following:
1
2
3
    if (value.toUpperCase().equals("TRUE")) {
        return true;
    }


After
Add dependency in your pom.xml
1
2
3
4
5
6
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.0</version>
    </dependency>


The updated code snippet are as bellows:
1
2
3
4
    String valueUpperCase = StringUtils.upperCase(value, Locale.ENGLISH);
    if(valueUpperCase.equals("TRUE")) {
        return true;
    }



2016/01/05

[Fortify] Fix Unreleased Resource: Streams

Problem
The following code snippet had been complain unreleased resource problem by Fortify : 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 @RequestMapping(value = "/importFile", method = RequestMethod.POST)
    public @ResponseBody
    void importFile(@RequestParam("file") MultipartFile multipartFile, Dbm002eFormBean formBean,
            Alerter alerter) throws IOException {

        ImportTypeEnum importType = ImportTypeEnum.IT0; // 匯入維度 (固定帶年度)
        String importId = formBean.getImpType(); // 匯入代號
        UpdTypeEnum updType = null; // 更新類別
        if ("0".equals(formBean.getUpdType())) {
            updType = UpdTypeEnum.UT0;
        } else if ("1".equals(formBean.getUpdType())) {
            updType = UpdTypeEnum.UT1;
        }
        Integer subtractYears = 5; // 減去X年
        String userId = UserHolder.getUser().getId(); // log in user id
        InputStream inputStream = null;
        try {
            inputStream = multipartFile.getInputStream();
            // file input stream
            String fileName = multipartFile.getOriginalFilename(); // file name
            
            if(!StringUtils.endsWith(fileName, ".xls") || !StringUtils.endsWith(fileName, ".XLS")) {
                throw new RuntimeException("只接受副檔名為 xls 的檔案, fileName = " + fileName);
            }

            importFileProcessService.saveImportFile(importType, importId, updType, subtractYears,
                    userId, inputStream, fileName);

            alerter.info("檔案上傳成功 (檔名:" + fileName + ")");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


How-To
It results from inputStream does not been close properly. Here has the updated code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@RequestMapping(value = "/importFile", method = RequestMethod.POST)
    public @ResponseBody
    void importFile(@RequestParam("file") MultipartFile multipartFile, Dbm002eFormBean formBean,
            Alerter alerter) throws IOException {

        ImportTypeEnum importType = ImportTypeEnum.IT0; // 匯入維度 (固定帶年度)
        String importId = formBean.getImpType(); // 匯入代號
        UpdTypeEnum updType = null; // 更新類別
        if ("0".equals(formBean.getUpdType())) {
            updType = UpdTypeEnum.UT0;
        } else if ("1".equals(formBean.getUpdType())) {
            updType = UpdTypeEnum.UT1;
        }
        Integer subtractYears = 5; // 減去X年
        String userId = UserHolder.getUser().getId(); // log in user id
        InputStream inputStream = null;
        try {
            inputStream = multipartFile.getInputStream();
            // file input stream
            String fileName = multipartFile.getOriginalFilename(); // file name
            
            if(!StringUtils.endsWith(fileName, ".xls") || !StringUtils.endsWith(fileName, ".XLS")) {
                throw new RuntimeException("只接受副檔名為 xls 的檔案, fileName = " + fileName);
            }

            importFileProcessService.saveImportFile(importType, importId, updType, subtractYears,
                    userId, inputStream, fileName);

            alerter.info("檔案上傳成功 (檔名:" + fileName + ")");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }





2015/12/04

[Fortify] Fix File Separator Issue

Problem

Code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
   /**
     * 複製檔案至新路徑
     * 
     * @param oldfile
     * @param status
     * @param fileName
     * @throws IOException
     */
    public void copyFile(File oldfile, String status, String fileName) throws IOException {
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMdd");
        String date = sdFormat.format(new Date());
        // 20151130 fix fortify file separator issue
        String newPath = BACKUP_FILE_PATH + status + "\\" + date + "\\";
        File file = new File(newPath);

        InputStream inStream = null;
        FileOutputStream fs = null;

        try {
            if (!file.exists()) {
                file.mkdirs();
            }
            // int bytesum = 0;
            int byteread = 0;

            inStream = new FileInputStream(oldfile);// 讀入原檔
            fs = new FileOutputStream(newPath + fileName);
            byte[] buffer = new byte[1444];

            while ((byteread = inStream.read(buffer)) != -1) {
                // bytesum += byteread; 位元組數 檔案大小
                fs.write(buffer, 0, byteread);
            }

        } catch (Exception e) {
            log.info("複製檔案錯誤", e);
        } finally {
            if (fs != null) {
                fs.close();
            }

            if (inStream != null) {
                inStream.close();
            }
        }
    }

How-to
updated code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    private final String FILE_SEPARATOR = FileSystems.getDefault().getSeparator();
 
    /**
     * 複製檔案至新路徑
     * 
     * @param oldfile
     * @param status
     * @param fileName
     * @throws IOException
     */
    public void copyFile(File oldfile, String status, String fileName) throws IOException {
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMdd");
        String date = sdFormat.format(new Date());
        // 20151130 fix fortify file separator issue
        String newPath = BACKUP_FILE_PATH + status + FILE_SEPARATOR + date + FILE_SEPARATOR;
        File file = new File(newPath);

        InputStream inStream = null;
        FileOutputStream fs = null;

        try {
            if (!file.exists()) {
                file.mkdirs();
            }
            // int bytesum = 0;
            int byteread = 0;

            inStream = new FileInputStream(oldfile);// 讀入原檔
            fs = new FileOutputStream(newPath + fileName);
            byte[] buffer = new byte[1444];

            while ((byteread = inStream.read(buffer)) != -1) {
                // bytesum += byteread; 位元組數 檔案大小
                fs.write(buffer, 0, byteread);
            }

        } catch (Exception e) {
            log.info("複製檔案錯誤", e);
        } finally {
            if (fs != null) {
                fs.close();
            }

            if (inStream != null) {
                inStream.close();
            }
        }
    }


Reference
[1] http://stackoverflow.com/questions/8075373/file-separator-vs-filesystem-getseparator-vs-system-getpropertyfile-separato