java源代码审计
需要注意的方法和关键字
常见危险方法:
- getParameter()
- getcookies()
- getQueryString()
- getheaders()
- Runtime.exec()
- logger.info
常见危险关键字: • password • upload • download
getParameter()
:该方法用于获取HTTP请求中的参数值。如果没有验证或过滤用户输入,则恶意用户可以通过构造特殊的请求来执行跨站脚本攻击(XSS)或SQL注入攻击。
getCookies()
:该方法可以返回客户端发送到服务器的所有cookie。如果应用程序没有正确设置安全cookie属性(例如HttpOnly和Secure),则恶意用户可以使用JavaScript访问这些cookie并窃取用户的身份验证令牌,从而发起会话劫持攻击。
getQueryString()
:类似于getParameter(),是一个用于获取HTTP请求参数的方法。具体来说,当客户端向服务器发送GET请求时,可以将请求参数附加到URL的查询字符串中(例如,在URL末尾添加“?key1=value1&key2=value2
”),而服务器就可以使用getQueryString()
方法从查询字符串中获取这些参数。如果没有正确过滤或编码用户输入,恶意用户可以在查询字符串中注入恶意代码,并对应用程序进行攻击。
getHeaders()
:如果没有正确验证或过滤头信息,攻击者可以通过修改请求头部内容,实施跨站脚本攻击或其他类型的攻击。
Runtime.exec()
:该方法允许应用程序执行系统命令。如果没有正确限制外部输入,则可能会导致恶意用户执行任意命令,包括删除文件、启动后门等。
logger.info()
:如果在日志记录器中记录了敏感信息,例如密码或其他机密数据,则攻击者可以利用此漏洞来获取敏感信息。
password
:如果明文存储密码,攻击者可以轻松地获取用户密码并进一步入侵应用程序或其他相关服务。
upload
:上传文件时,如果没有正确限制文件类型、大小和内容,则可能会导致恶意用户上传包含恶意代码的文件,例如web shell,实现远程命令执行攻击。
download
:如果下载文件时没有正确限制文件类型、大小和内容,则可能会导致恶意用户在下载过程中注入恶意代码,例如利用浏览器漏洞进行攻击
sql注入的防范
sql注入通常是因为使用了 String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
这种拼接sql语句的方式,我们可以使用预编译的方式来防范sql注入,如下:
1String sql = "select * from user where username = ? and password = ?";
2PreparedStatement ps = conn.prepareStatement(sql);
3ps.setString(1, username);
4ps.setString(2, password);
5ResultSet rs = ps.executeQuery();
这样预编译会把 ?
位置的参数当成字符串来处理,而不是当成sql语句的一部分,所以就不会出现sql注入的问题了。
xss的防范
xss的防范主要是对用户输入的内容进行过滤,防止用户输入的内容中包含恶意的脚本代码,如下:
1String username = request.getParameter("username");
2username = username.replaceAll("<", "<").replaceAll(">", ">");
这样就可以把用户输入的内容中的 < 和 > 替换成 < 和 >,这样就可以防止用户输入的内容中包含恶意的脚本代码了。
路径遍历的防范
目录遍历漏洞,是一种常见的Web安全漏洞。攻击者通过利用该漏洞,可以访问应用程序中未经授权的文件和目录。
当开发人员使用用户提供的输入构建文件路径时,没有对用户输入进行合法性验证和过滤,从而导致攻击者可以在访问文件时绕过应用程序的安全检查。例如,攻击者可以通过修改URL参数中的目录跳转符来访问系统文件或其他目录中的文件,甚至可以执行任意代码。
错误的(使用字符串拼接得到路径)
1String fileName = request.getParameter("fileName");
2String filePath = "/opt/files/" + fileName;
3File file = new File(filePath);
修复的,使用 new File(baseDir, fileName) 的方式
1String fileName = request.getParameter("fileName");
2String baseDir = "/opt/files/";
3File file = new File(baseDir, fileName);
文件上传的防范
文件上传漏洞是: 上传文件时,如果没有正确限制文件类型、大小和内容,则可能会导致恶意用户上传包含恶意代码的文件,例如web shell,实现远程命令执行攻击。
通常是因为没有限制文件的大小和类型,我们可以通过 file.getSize()
和 file.getContentType()
来限制文件的大小和类型,如下:
1if (file.getSize() > 1024 * 1024) {
2 return "文件大小不能超过1M";
3}
4if (!file.getContentType().equals("image/jpeg")) {
5 return "文件类型只能是jpg";
6}
7byte[] bytes = file.getBytes();
8if (bytes[0] != (byte) 0xFF || bytes[1] != (byte) 0xD8) {
9 return "文件内容不是jpg";
10}
这样就可以限制文件的内容了。
文件的魔数是一种用于识别文件格式的机制,通常是指文件开头固定位置的几个字节。不同类型的文件具有不同的魔数,操作系统会根据文件的魔数来确定文件的类型和打开方式。 可以用16进制编辑器打开文件(比如命令行中:
certutil xxx.zip | more
),查看文件的前几个字节,就可以看到文件的魔数了。 不同的文件类型有不同的魔数,比如说:
1JPEG 图像文件的魔数为 FF D8 FF
2PNG 图像文件的魔数为 89 50 4E 47 0D 0A 1A 0A
3GIF 图像文件的魔数为 47 49 46 38 39 61 或者 47 49 46 38 37 61
4PDF 文件的魔数为 25 50 44 46
5ZIP 压缩文件的魔数为 50 4B 03 04