http://xxx.com/a.jsp?id=1HttpServletRequest request,HttpServletResponse ressponse){JdbcConnection conn =newJdbcConnection();finalString sql ="select * from product where pname like '%"+resuest.getParameter("id")+"%'"conn.execqueryResultSet(sql);}
上述代码中,百分号没有闭合,导致了注入漏洞的存在
此时的查询语句为:
finalString sql ="select * from product where panme l ike '%1' or '%'='%'"
不同状态下可能存在注入的情况:
# 1. 伪静态http://1223.com/122.htmlString id =url.Substring(url.length-9,4);finalString sql ="select *from product where di = "+ idconn.execqueryResultSet(sql);# 2. 登录框POST /login.actionusername=admin&password=adminString sql ="select * from usertable where name ='"+username+"' and password = '"+ password +"'"# 3. header头参数引起的注入username,cookie,X-Forward-For等String referer =request.getHeader("referer");String sql ="update TABLE set referer = '"+ referer +"'";
如果使用参数化查询,则在SQL语句中使用占位符表示需在运行时确定的参数值。参数化查询使得SQL查询的语义逻辑被预先定义,而实际的查询参数值则等到程序运行时再确定。参数化查询使得数据库能够区分SQL语句中语义逻辑和数据参数,以确保用户输入无法改变预期的SQL查询语义逻辑。在Java中,可以使用java.sql.PreparedStatement来对数据库发起参数化查询。在这个正确示例中,如果一个攻击者将itemName输入为name' OR 'a' = 'a,这个参数化查询将免受攻击,而是会查找一个itemName匹配name' OR 'a' = 'a这个字符串的条目。
# 1. 直接从request中获取参数然后拼接
String sql = "select * from product where pname like '%" + request.getParameter("name") + "%'";
# 2. 参数由方法传递而来
String sql = "select * from product where pname like '%" + name + "%'";
<select>
select * from table where name like '%$value$%'
<select>
select * from news where id in (${id})
select * from news where title = '新年' order by ${time} asc;
Srting hql = "select e frin Tfqeuipmentfaultdetails e where e.equipmentnumber = ?";
Query query = session,createQuery(hql);
query.setString(0, repairNumber.trim());
Statement stmt = null;
ResultSet rs = null;
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String sqlString = "SELECT * FROM t_item WHERE owner='" + userName + "' AND itemName='" + request.getParameter("itemName") + "'";
stmt = connection.createStatement();
rs = stmt.executeQuery(sqlString);
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
PreparedStatement stmt = null
ResultSet rs = null
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
// ...Ensure that the length of userName and itemName is legitimate
// ...
String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName=?";
stmt = connection.prepareStatement(sqlString);
stmt.setString(1, userName);
stmt.setString(2, itemName);
rs = stmt.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
CallableStatement = null
ResultSet results = null;
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
cs = connection.prepareCall("{call sp_queryItem(?,?)}");
cs.setString(1, userName);
cs.setString(2, itemName);
results = cs.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
CREATE PROCEDURE sp_queryItem
@userName varchar(50),
@itemName varchar(50)
AS
BEGIN
DECLARE @sql nvarchar(500);
SET @sql = 'SELECT * FROM t_item
WHERE owner = ''' + @userName + '''
AND itemName = ''' + @itemName + '''';
EXEC(@sql);
END
GO
CallableStatement = null
ResultSet results = null;
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
// ... Ensure that the length of userName and itemName is legitimate
// ...
cs = connection.prepareCall("{call sp_queryItem(?,?)}");
cs.setString(1, userName);
cs.setString(2, itemName);
results = cs.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
CREATE PROCEDURE sp_queryItem
@userName varchar(50),
@itemName varchar(50)
AS
BEGIN
SELECT * FROM t_item
WHERE userName = @userName
AND itemName = @itemName;
END
GO
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query sqlQuery = session.createSQLQuery("select * from t_item where owner = '" + userName + "' and itemName = '" + itemName + "'");
List<Item> rs = (List<Item>) sqlQuery.list();
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = '" + userName + "' and item.itemName = '" + itemName + "'");
List<Item> hrs = (List<Item>) hqlQuery.list();
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = ? and item.itemName = ?");
hqlQuery.setString(1, userName);
hqlQuery.setString(2, itemName);
List<Item> rs = (List<Item>) hqlQuery.list();
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = :owner and item.itemName = :itemName");
hqlQuery.setString("owner", userName);
hqlQuery.setString("itemName", itemName);
List<Item> rs = (List<Item>) hqlQuery.list();
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query sqlQuery = session.createSQLQuery("select * from t_item where owner = ? and itemName = ?");
sqlQuery.setString(0, owner);
sqlQuery.setString(1, itemName);
List<Item> rs = (List<Item>) sqlQuery.list();
<select id="getItems" parameterClass="MyClass" resultClass="Item">
SELECT * FROM t_item WHERE owner = #userName# AND itemName = #itemName#
</select>
#符号括起来的userName和itemName两个参数指示iBATIS在创建参数化查询时将它们替换成占位符:
String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName=?";
PreparedStatement stmt = connection.prepareStatement(sqlString);
stmt.setString(1, myClassObj.getUserName());
stmt.setString(2, myClassObj.getItemName());
ResultSet rs = stmt.executeQuery();
// ... convert results set to Item objects
<select id="getItems" parameterClass="MyClass" resultClass="items">
SELECT * FROM t_item WHERE owner = #userName# AND itemName = '$itemName$'
</select>
String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName='" + myClassObj.getItemName() + "'";
PreparedStatement stmt = connection.prepareStatement(sqlString);
stmt.setString(1, myClassObj.getUserName());
ResultSet rs = stmt.executeQuery();
// ... convert results set to Item objects
public List<Book> queryBooks(List<Expression> queryCondition)
{
/* ... */
try
{
StringBuilder sb = new StringBuilder("select * from t_book where ");
Codec oe = new OracleCodec();
if (queryCondition != null && !queryCondition.isEmpty())
{
for (Expression e : queryCondition)
{
String exprString = e.getColumn() + e.getOperator() + e.getValue();
String safeExpr = ESAPI.encoder().encodeForSQL(oe, exprString);
sb.append(safeExpr).append(" and ");
}
sb.append("1=1");
Statement stat = connection.createStatement();
ResultSet rs = stat.executeQuery(sb.toString());
//other omitted code
}
}
/* ... */
}