JAVAWEB安全开发

晚上在看司马的博客,看到一篇关于JAVA安全的,基础的,蛮不错的,给大家分享下

文章来源是司马的博客:http://www.nxadmin.com/web/1332.html

================================================================================

SQL注入

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

漏洞示例:

 1 <%@page import="java.sql.*"%>
 2 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title> </title>
 8 </head>
 9 <body>
10 <%
11         String user = request.getParameter("user");
12         String pass = request.getParameter("pass");
13         Class.forName("com.mysql.jdbc.Driver");
14         Connection con = (Connection)
15         DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root" ,"");
16         Statement st= con.createStatement();
17         ResultSet rs=st.executeQuery("select * from users where username=‘"+user+"‘ and password=‘"+pass+"‘ limit 0,1");
18         if(rs.next())
19         {
20                 out.println("Login success");
21         }
22         else
23         {
24                 out.println("Login failed");
25         }
26 %>

在上述代码中,开发者使用声明的类来创建一个SQL语句,并执行它来获取一个有效用户的用户名和密码。由于使用拼接SQL语句,并且没有做任何防注入的手段,导致存在SQL注入漏洞,可以绕过登录验证。

修复后的代码如下:

 1 <%@page import="java.sql.*"%>
 2 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title></title>
 8 </head>
 9 <body>
10 <%
11     String user = request.getParameter("user");
12     String pass = request.getParameter("pass");
13     Class.forName("com.mysql.jdbc.Driver");
14 Connection con = (Connection)
15 DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root" , "");
16     PreparedStatement ps=(PreparedStatement) con.prepareStatement("select * from users where username=? and password=? limit 0,1");
17     ps.setString(1,user);
18     ps.setString(2,pass);
19     ResultSet rs=ps.executeQuery();
20     if(rs.next())
21     {
22         out.println("Login success");
23     }
24     else
25     {
26         out.println("Login failed");
27     }
28 %>
29 </body>

修复后的代码使用了PreparedStatement预编译的方式,使用这种方式无需对传入的参数进行过滤等处理,因为由于PreparedStatement内置了字符过滤,因此是能够防止SQL注入的。

数据明文存储

11年底CSDN的数据在网上泄漏,据说库中的密码都是明文存储的,因此导致非常大的影响。如果使用了复杂的加密存储,即时数据泄漏,密码也有可能不会破解成功,下面看看JAVA代码中数据明文存储的设计缺陷是如何形成的。

漏洞示例:

 1 <%@page import="java.sql.*"%>
 2 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title></title>
 8 </head>
 9 <body>
10 <%
11 String user=request.getParameter("user");
12 String pass=request.getParameter("pass");
13 Class.forName("com.mysql.jdbc.Driver");
14 Connection con=(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root" ,"");
15 PreparedStatement ps = (PreparedStatement) con.prepareStatement("insert into users_crypt values(?,?)");
16 ps.setString(1,user);
17 ps.setString(1,pass);
18 int res = ps.executeUpdate();
19 if(res>0)
20 {
21 out.println("Register success");
22 }
23 else
24 {
25 out.println("Register failed");
26 }
27 %>
28 </body>

可以看到上面的代码对获取到的user和pass的没有做任何的加密处理,直接存储到数据库中,导致存在明文存储的缺陷。

修复后的代码如下:

 1 <%@page import="java.util.Calendar"%>
 2 <%@page import="java.text.SimpleDateFormat"%>
 3 <%@page import="java.text.DateFormat"%>
 4 <%@page import="java.math.BigInteger"%>
 5 <%@page import="java.security.MessageDigest"%>
 6 <%@page import="java.sql.*"%>
 7 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 8 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 9 <html>
10 <head>
11 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
12 <title></title>
13 </head>
14 <body>
15 <%
16     String user=request.getParameter("user");
17     String pass=request.getParameter("pass");
18     DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
19     Calendar cal = Calendar.getInstance();
20     String reg_time = (dateFormat.format(cal.getTime())).toString();
21     String original = pass+reg_time;
22     String s = pass+reg_time;
23     MessageDigest m = MessageDigest.getInstance("MD5");
24     m.update(s.getBytes(),0,s.length());
25     String calc_hash = new BigInteger(1,m.digest()).toString(16);
26     if(calc_hash.length()<32)
27     {
28         calc_hash = "0"+calc_hash;
29     }
30     Class.forName("com.mysql.jdbc.Driver");
31     Connection con=(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root" ,"");
32     PreparedStatement ps = (PreparedStatement) con.prepareStatement("insert into users_crypt values(?,?,?)");
33     ps.setString(1,user);
34     ps.setString(2,calc_hash);
35     ps.setString(3,reg_time);
36     int res = ps.executeUpdate();
37     if(res>0)
38     {
39         out.println("Register success");
40     }
41     else
42     {
43         out.println("Register failed");
44     }
45 %>
46 </body>
47 </html>

修复后的代码将用户注册的时候输入的密码和注册时间组合加密之后保存在数据库中,这样如果数据泄漏,不阅读源代码很难将密码破解成明文形式,大大降低了泄密之后的影响。

失效的会话管理

该漏洞主要是因为Web应用程序没有正确的执行会话管理,例如用户登陆前的会话Cookie和登录后的是一样的,另外一个例子是当用户点击退出的时候,Session不会失效。

示例漏洞代码:

 1 <%@page import="java.sql.*"%>
 2 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title> </title>
 8 </head>
 9 <body>
10 <%
11     String user = request.getParameter("user");
12     String pass = request.getParameter("pass");
13     Class.forName("com.mysql.jdbc.Driver");
14     Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root" , "");
15     PreparedStatement ps=(PreparedStatement) con.prepareStatement("select * from users where username=? and password=? limit 0,1");
16     ps.setString(1,user);
17     ps.setString(2,pass);
18     ResultSet rs=ps.executeQuery();
19     if(rs.next())
20     {
21         session.setAttribute("useracc", rs.getString("user"));
22         out.println("Login success");
23     }
24     else
25     {
26         out.println("Login failed");
27     }
28 %>
29 </body>

修复后的代码:

 1 <%@page import="java.sql.*"%>
 2 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 7 <title> </title>
 8 </head>
 9 <body>
10 <%
11     String user = request.getParameter("user");
12     String pass = request.getParameter("pass");
13     Class.forName("com.mysql.jdbc.Driver");
14     Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/userdb", "root" , "");
15     PreparedStatement ps=(PreparedStatement) con.prepareStatement("select * from users where username=? and password=? limit 0,1");
16     ps.setString(1,user);
17     ps.setString(2,pass);
18     ResultSet rs=ps.executeQuery();
19     if(rs.next())
20     {
21         session.invalidate();
22         request.getSession(true);
23         session.setAttribute("useracc", rs.getString("user"));
24         out.println("Login success");
25     }
26     else
27     {
28         out.println("Login failed");
29     }
30 %>
31 </body>

以上修复后的代码中,用户在登录的时候,首先会让之前的session失效,然后又获取新的seesion。

XSS漏洞

Xss漏洞小伙伴们应该都比较熟悉了,攻击者可以向网页中注入恶意的JS或者HTML代码,有反射XSS、存储XSS、DOM XSS三种。

漏洞示例:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>XSS Vulnerable</title>
 8 </head>
 9 <body>
10     <form action="xss-vuln.jsp" method="post">
11         Enter your name: <input type="text" name="name"><input type="submit">
12     </form>
13
14 <%
15     if(request.getMethod().equalsIgnoreCase("post"))
16     {
17         String name = request.getParameter("name");
18         if(!name.isEmpty())
19         {
20             out.println("<br>Hi "+name+". How are you?");
21         }
22     }
23 %>
24
25 </body>
26 </html>

从上面漏洞代码中可以看到,对用户提交的name参数没有做任何的输入过滤和输出的编码,直接输出在HTML代码中,导致存在反射XSS漏洞。

修复后的代码:

 1 <%@page import="org.apache.commons.lang.StringEscapeUtils"%>
 2 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 3 Patch
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>XSS Patched</title>
 9 </head>
10 <body>
11 <form action="xss-patch.jsp" method="post">
12 Enter your name: <input type="text" name="name"><input type="submit">
13 </form>
14
15 <%
16     if(request.getMethod().equalsIgnoreCase("post"))
17     {
18         String name =
19         StringEscapeUtils.escapeHtml(request.getParameter("name"));
20         if(!name.isEmpty())
21         {
22             out.println("<br>Hi "+name+". How are you?");
23         }
24     }
25 %>
26 </body>

上面修复后的代码对用户提交的name参数进行了HTML的编码处理,使用了StringEscapeUtils类的escapeHtml方法,该方法会自动对特殊符号进行HTML编码处理。该类是包含在 commons-lang-2.4.jar包中的。

越权漏洞

如果一个Web应用程序不正确检查用户是否被授权访问的特定的资源,就有可能导致产生越权漏洞。例如帐号A在登录的状态下,遍历访问请求中的ID就可以查看其它人的相关信息。

漏洞示例代码:

 1 <%@page import="java.util.Enumeration"%>
 2 <%@ page import="java.sql.*" %>
 3 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Account Balance</title>
 9 </head>
10 <body>
11 <%
12     int flag = 0;
13     Enumeration e = session.getAttributeNames();
14     while (e.hasMoreElements())
15     {
16         String name = (String) e.nextElement();
17         String value = session.getAttribute(name).toString();
18         if(name.equals("useracc") && !(value.isEmpty()))
19         {
20             flag = 1;
21             break;
22         }
23     }
24     if(flag == 1)
25     {
26         String accno = request.getParameter("accno");
27         Class.forName("com.mysql.jdbc.Driver");
28         Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "");
29         PreparedStatement ps = (PreparedStatement) con.prepareStatement("select * from account_balance where accno=? limit 0,1");
30         ps.setString(1,accno);
31         ResultSet rs = ps.executeQuery();
32         if(rs.next())
33         {
34             String s = rs.getString("balance");
35             out.println("<h1>Welcome to your account</h1>");
36             out.println("<br>Account Number: "+session.getAttribute("useracc"));
37             out.println("<br>Your current balance is: "+s);
38         }
39         else
40         {
41             out.println("Error: Contact administrator.");
42         }
43     }
44     else
45     {
46         response.sendRedirect("login.jsp");
47     }
48 %>
49 </body>
50 </html>

在上面的代码中,没有判断用户Session,导致通过修改accno的值就可以遍历返回的结果信息。

修复后的代码:

 1 <%@page import="java.util.Enumeration"%>
 2 <%@ page import="java.sql.*" %>
 3 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Account Balance</title>
 9 </head>
10 <body>
11 <%
12     int flag = 0;
13     Enumeration e = session.getAttributeNames();
14     while (e.hasMoreElements())
15     {
16         String name = (String) e.nextElement();
17         String value = session.getAttribute(name).toString();
18         if(name.equals("useracc") && !(value.isEmpty()))
19         {
20             flag = 1;
21             break;
22         }
23     }
24
25     if(flag == 1)
26     {
27         String sess_accno = session.getAttribute("useracc").toString();
28         String accno = request.getParameter("accno");
29         if(sess_accno.equals(accno))
30         {
31             Class.forName("com.mysql.jdbc.Driver");
32             Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "");
33             PreparedStatement ps = (PreparedStatement) con.prepareStatement("select * from account_balance where accno=? limit 0,1");
34             ps.setString(1,accno);
35             /*
36             This line will be better
37             ps.setString(1,sess_accno);
38             */
39             ResultSet rs = ps.executeQuery();
40             if(rs.next())
41             {
42                 String s = rs.getString("balance");
43                 out.println("<h1>Welcome to your account</h1>");
44                 out.println("<br>Account Number: "+session.getAttribute("useracc"));
45                 out.println("<br>Your current balance is: "+s);
46             }
47             else
48             {
49                 out.println("Error: Contact administrator.");
50             }
51         }
52         else
53         {
54             out.println("Unauthorized Access Detected");
55         }
56     }
57     else
58     {
59         response.sendRedirect("login.jsp");
60     }
61 %>
62 </body>
63 </html>

上面修复后的代码,判断了用户的Session,在为True的情况下才能够查看返回的信息,因此当用户遍历accno的值来尝试获取返回结果时,会提示无权访问。

时间: 2024-08-11 01:24:28

JAVAWEB安全开发的相关文章

学习JavaWeb项目开发需要掌握的技术

武汉java培训学习JavaWeb项目开发需要掌握的技术,国内外信息化建设已经进入基于Web应用为核心的阶段, java作为应用于网络的最好语言,前景无限看好.然而,就算用Java建造一个不是很烦琐的web应用,也不是件轻松的事情.概括一下,实施Java的WEB项目需要掌握的技术如下:Java语言面向对象分析设计思想设计模式和框架结构XML语言网页脚本语言数据库应用服务器集成开发环境下面我们具体地看每个技术.1.Java语言Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.

当用Myeclipse8.6集成开发环境,进行JavaWeb项目开发的时候,用集成开发环境中的run Server进行程序调试时,出现如下错误解决方案

当用Myeclipse8.6集成开发环境,进行JavaWeb项目开发的时候,用集成开发环境中的run Server进行程序调试时,出现如下错误解决方案: 'Starting Tomcat v6.0 Server at localhost'has encountered a problem 错误提示: Several ports(8080,8009)required by Tomcatv6.0 Server at localhost are already in use.The server ma

搭建JavaWeb应用开发环境

下载和安装Tomcat服务器 下载Tomcat安装程序包:http://tomcat.apache.org/,下载一个zip版本,解压到本地即完成了Tomcat的安装. 测试是否安装成功:进入Tomcat目录,双击 bin 目录下的 startup.bat 文件启动Tomcat服务器,在浏览器中输入http://localhost:8080/,有内容出来就表示成功了. Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件.

(转)一个JavaWeb项目开发总结

原文地址:http://www.cnblogs.com/lzb1096101803/p/4907775.html 一.学会如何读一个JavaWeb项目源代码 步骤:表结构->web.xml->mvc->db->spring ioc->log->代码 先了解项目数据库的表结构,这个方面是最容易忘记的,有时候我们只顾着看每一个方法是怎么进行的,却没有去了解数据库之间的主外键关联.其实如果先了解数据库表结构,再去看一个方法的实现会更加容易. 然后需要过一遍web.xml,知道

JavaWeb应用开发使用jetty札记

应该做点变化了,决定使用Maven来管理工程,并且在Java Web开发中使用Jetty来作为测试容器. 1.JavaWeb工程配置jetty-maven-plugin插件 <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.6.v20141205</version> &

Javaweb项目开发的前后端解耦的必要性

JavaWeb项目为何我们要放弃jsp?为何要前后端解耦?为何要动静分离? 使用jsp的痛点: 1.jsp上动态资源和静态资源全部耦合在一起,服务器压力大,因为服务器会收到各种静态资源的http请求,动态代码的等等,除非你使用nginx. 万一你的java代码出现了bug,你的页面是显示不出来的,直接蹦到了5xx页面,用户体验极差. (现在javaWeb项目业界的标准是nginx+tomcat,动静分离,请求先到nginx,所有的静态资源请求全部交给nginx,动态资源全部给tomcat,此外n

JavaWeb 项目开发中的技术总结

前言: 在项目开发过程中的一点点指导思想 1.环境准备 win系统 Eclipse 开发平台 maven tomcat Mysql 数据库,mysql5.6 操作数据库的jar 包 JDBC 连接数据库的jar,mysql-connector-java-xxx.jar DbUtils 操作数据库jar包,基于 JDBC的封装 数据源jar,可以有c3p0.dbcp 日志文件,log4j 前台编写jquery需要的js 编写前台使用的公用样式 bootstrap 2.需求 创建一个表,对该表进行增

JavaWeb入门级开发知识整理

一.开发环境所需软件 1.Tomcat Tomcat是Apache-Jarkarta 的一个免费/开放源码的子项目,是一个支持JSP和Servelt技术的容器,它同时又是一个Web服务器软件. 2.MyEclipse MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java.Java EE以及移动应用的开发.MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持相当不错. 3.MySQL MySQL是一个开源轻便的

TomCat以及JavaWeb的开发目录结构

1. 部署并启动 tomcat 服务器.1). 解压 apache-tomcat-6.0.16.zip 到一个非中文目录下2). 配置一个环境变量. java_home(指向 JDK 安装的根目录) 或 jre_home3). 通过双击 apache-tomcat-6.0.16\bin 目录下的 startup.bat, 启动服务器4). 可以在浏览器中输入 localhost:8080 来检验 Tomcat 安装是否正确. 5). 若已经启动了一个 Tomcat 应用, 若再启动同一个 Tom

深入分析JavaWeb Item33 -- 开发自己简易的JDBC框架

一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.getDatabaseMetaData()获得代表DatabaseMetaData元数据的DatabaseMetaData对象. DataBaseMetaData对象的常用方法: getURL():返回一个String类对象,代表数据库的URL. getUserName():返回连接当前数据库管理系统的用户名.