java代码审计和安全漏洞修复

java代码审计和安全漏洞修复

开源:奇安信代码卫士

官网使用

  • 选择源码并上传

  • 检测

  • 查看漏洞

  • 详情

gitee服务使用

在项目的【服务】项下,选择【奇安信代码卫士】

【创建分析】

新建分析,选择【检测分支】,支持扫描的语言:php、java/jsp、python、c/c++,java 版本最高支持 1.8,点击【提交】

查看扫描结果

https://codescan.qianxin.com/#/login
https://blog.csdn.net/SHELLCODE_8BIT/article/details/129281099
https://blog.csdn.net/qq_36434219/article/details/127659944

非开源:思客云找八哥

  • 详情

错误类型以及修改方法

1.硬编码

  • 漏洞
    public void hardcodedCredentials(String name, String password) {
        if(name.equals("admin") && password.equals("admin")) {
            // Do something
        }
    }

修复思路:密码等敏感数据不要直接从代码中读取,可以使用配置文件或数据库存储的方式来存储系统所需的数据,录入数据时,还可以在对敏感数据做加密处理之后再进行数据的录入

  • 修复方法1
import org.springframework.beans.factory.annotation.Value;

    @Value("${admin.username}")
    private String adminUsername;

    @Value("${admin.password}")
    private String adminPassword;

    public void checkCredentials(String name, String password) {
        if(name.equals(adminUsername) && password.equals(adminPassword)) {
            // Do something
        }
    }
  • 修复方法2
    public void hardcodedCredentials(String name, String password) {
        if (name.equals(System.getenv("ADMIN_NAME")) && password.equals(System.getenv("ADMIN_PASSWORD"))) {
        }
    }

2. 路径操作

  • File漏洞
    public void pathManipulation(HttpServletRequest request, String rootPath) throws FileNotFoundException {
        String filename = request.getParameter("filename");
        String fullFileName = rootPath + filename;
        File downFile = new File(fullFileName);
    }

思路:对输入文件进行验证,使用安全的读取文件的方法

  • 修复方法
import org.apache.commons.io.FileUtils;

    public void pathManipulation(HttpServletRequest request, String rootPath) throws FileNotFoundException {
        String filename = request.getParameter("filename");

        Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
        Matcher matcher = pattern.matcher(filename);
        filename = matcher.replaceAll("");

        File downFile = FileUtils.getFile(filename, "dddd");
        if (!downFile.exists()) {
            throw new FileNotFoundException("File not found: " + filename);
        } else {
            // Do something with downFile
        }
    }
  • Stream漏洞
    public void pathManipulation2(HttpServletRequest request, String rootPath) throws FileNotFoundException {
        String filename = request.getParameter("filename");
        String fullFileName = rootPath + filename;
        InputStream is = new BufferedInputStream(new FileInputStream(fullFileName));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(fullFileName));
    }
  • 修复方法
    public void pathManipulation2(HttpServletRequest request, HttpServletResponse response, String rootPath) throws IOException {
        String filename = request.getParameter("filename");
        String fullFileName = rootPath + filename;

        Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
        Matcher matcher = pattern.matcher(filename);
        filename = matcher.replaceAll("");

        File f = FileUtils.getFile(filename);

        if(f != null){
            InputStream is = new BufferedInputStream(new FileInputStream(f));
            OutputStream os = new BufferedOutputStream(response.getOutputStream());
            OutputStream os2 = new BufferedOutputStream(new FileOutputStream(f));
        }
    }
  • File封装类漏洞
import java.io.File;
public class FileUtil extends File {

    static String fileFullPath;

    public FileUtil(String pathname) {
        super(pathname);
        fileFullPath = pathname;
    }

    //其他操作

}

// 使用
FileUtil fileUtil = new FileUtil(fullFileName);
  • 修复方法
FileUtil fileUtil2 = (FileUtil) FileUtils.getFile(filename);

https://www.cnblogs.com/jayus/p/11423769.html
https://blog.csdn.net/m0_71745754/article/details/128675164
https://blog.csdn.net/qq_33204709/article/details/127968923
https://blog.csdn.net/qq_41085151/article/details/113525348
https://blog.csdn.net/qq_29384639/article/details/82705421

3. 路径操作 - Zip文件条目覆盖

  • 漏洞
    public void zipEntryOverwrite(ZipEntry entry, String dstFileName) throws Exception {
        File outFile = new File(dstFileName, entry.getName());
        OutputStream outputStream = new FileOutputStream(outFile);
        // Write data to outputStream
    }

思路:判断压缩文件路径

  • 修复方法
    public void zipEntryOverwrite(ZipEntry entry, String dstFileName) throws IOException {
        String entryName = Paths.get(entry.getName()).normalize().toString();
        // Reject entries that try to escape the target directory
        if (entryName.startsWith("..")) {
            throw new IOException("Bad zip entry: " + entry.getName());
        }
        // 创建一个新的文件路径
        String newFilePath = Paths.get(dstFileName, entryName).toString();
        // 创建新文件并获取输出流
        File outFile = new File(newFilePath);
        OutputStream outputStream = new FileOutputStream(outFile);
        // Write data to outputStream
    }

https://www.cnblogs.com/jinqi520/p/9391596.html

4. SQL注入

  • 漏洞
    public void sqlInjection(String orderId,Connection conn) throws Exception {
        String sql = "From User u on where 1=1";
        if(!orderId.equals("")){
            sql = sql + " and u.id = "+ orderId;
        }
        if(!orderId.equals("")){
            sql = sql + " and u.id like '%"+ orderId + "%'";
        }
        PreparedStatement stmt = conn.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
    }

思路:用户的输入不能直接嵌套在SQL语句中,使用参数设置

  • 修复方法
    public void sqlInjection(String orderId, Connection conn) throws Exception {
        String sql;
        PreparedStatement stmt;
        ResultSet rs;
        if (!orderId.isEmpty()) {
            sql = "SELECT * FROM User u WHERE u.id = ? ORDER BY id DESC";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, orderId);
        } else {
            sql = "SELECT * FROM User u ORDER BY id DESC";
            stmt = conn.prepareStatement(sql);
        }
        rs = stmt.executeQuery();
    }
    public void safeSQLExecution(Connection conn, List<String> ids) throws Exception {
        String sql = "SELECT * FROM some_table WHERE id = ?";  // '?' 是一个参数占位符
        PreparedStatement stmt = conn.prepareStatement(sql);
        for (String id : ids) {
            stmt.setString(1, id);  // 使用用户输入替代参数占位符
            ResultSet rs = stmt.executeQuery();
            // 处理结果集...
        }
    }

5. SQL注入 - Hibernate

  • 漏洞
    @PersistenceContext
    private EntityManager entityManager;

    public void sqlInjectionHibernate(String orderId) {
        String sql = "From User u on where 1=1";
        if(!orderId.equals("")){
            sql = sql + " and u.id = "+ orderId;
        }
        sql = sql + " order by id desc";
        Session session = entityManager.unwrap(Session.class);
        Query query = session.createQuery(sql);
        // Execute the query
    }
  • 修复方法
    public void sqlInjectionHibernate(String orderId, Session session) throws Exception {
        String hql = "FROM UserEntity u WHERE 1=1";
        if (!orderId.equals("")) {
            hql = hql + " AND u.id = :orderId";
        }
        hql = hql + " ORDER BY id DESC";

        Query query = session.createQuery(hql);
        if (!orderId.equals("")) {
            // Set the parameter
            query.setParameter("orderId", Integer.parseInt(orderId));
        }
        List<UserEntity> users = query.list();
        // Process the users
    }
    public void sqlInjectionL(List<String> orderIds, Session session) throws Exception {
        String sql = "delete from UserEntity u where u.id in ("+ orderIds +")";
        Query query = session.createQuery(sql);
        query.setParameterList("orderIds", orderIds);
        // Process the result set
    }

6. XML外部实体注入,有风险的XML外部实体解析

  • 漏洞
    public void xxeInjection(String xmlFilePath) throws Exception {
        // Process the document
        String baseDir = System.getProperty("user.dir");
        File file = new File(baseDir);
        String configFile = file.getParent()+"\\conf\\server.xml";
        XmlUtil xmlut = new XmlUtil();
        String port = getMyPort(configFile);

    }

    public String getMyPort(String xmlFilePath) throws ParserConfigurationException, IOException, SAXException {
        String port = "";
        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFilePath);
        Element root = document.getDocumentElement();
        NodeList list = root.getElementsByTagName("service");
        Node ServiceNode = list.item(0);
        list = ServiceNode.getChildNodes();
        // ...
        return port;
    }

思路:XXE 注入的主要入口点是 DTD。防止 XXE 漏洞的最简单方法是禁用应用程序的 DTD,禁用 DTD 可能并不适用于所有场景,也可以使用输入验证来防止恶意注入

  • 修复方法
    public String getMyPort(String xmlFilePath) throws ParserConfigurationException, IOException, SAXException {
        String port = "";
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        //REDHAT
        //https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
        dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
        dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");

        //OWASP
        //https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        // Disable external DTDs as well
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        // and these as well, per Timothy Morgan's 2014 paper:"XML Schema, DTD, and Entity Attacks"
        dbf.setXIncludeAware(false);
        dbf.setExpandEntityReferences(false);

        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse(xmlFilePath);

        Element root = document.getDocumentElement();
        NodeList list = root.getElementsByTagName("service");
        Node ServiceNode = list.item(0);
        list = ServiceNode.getChildNodes();

        // 获取真正的port,省略
        return port;
    }

https://www.codenong.com/56777287/
https://www.jianshu.com/p/9b4e1bce8da2

7. 空加密密钥

  • 漏洞
    public void nullEncryptionKey(String key) throws Exception {
        if(key == null) key = "";
    }
  • 修复方法
    public void nullEncryptionKey(byte[] input) throws Exception {
        byte[] key = null;
        // An actual encryption key should be used here
        key = "Some real key".getBytes();
        if (key == null || key.length != 16) {
            throw new IllegalArgumentException("Key is invalid");
        }
    }

8. 系统信息泄露

  • 漏洞
    public String systemInformationLeak( String json) {
        PrintWriter w = null;
        w.write(json);

        try {
            // Do something
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return null;
    }
  • 修复方法
    public String systemInformationLeak() {
        try {
            // Do something
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
            return "An error occurred. Please try again later.";
        }
        return null;
    }

9. 私密违反:私密信息序列化

  • 漏洞
public class UserTest implements Serializable {
    private String username;
    private String pwd;
    private String password;
}
  • 修复⽅式1,采⽤hash加密
public class UserTest implements Serializable {

    private String username;
    private String pwd;
    private String password;
    public String getPassword() {
        return passwordHash;
    }

    public void setPassword(String password) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        this.passwordHash = passwordEncoder.encode(password);
    }
}
  • 修复⽅式1,直接删除Serializable
public class User {
    private String username;
    private transient String pwd;
    private String passwordHash;
}

其他参考链接

https://blog.csdn.net/a3562323/article/details/105389651

猜你喜欢

转载自blog.csdn.net/qq_23858785/article/details/131253599