JAVA安全
JAVA SQL注入
session参数绑定,存储过程这样的注入。 // 利用 session 防御,session 内容正常情况下是用户无法修改的 select * from users where user = “'” + session.getAttribute(“UserID”) + “'”;
预编译
当java JDBC采用preparestatment预编译之后,sql语句会先编译好语句逻辑,参数位置使用占位符?,那么参数就不会执行sql逻辑,从而实现防御大部分的sql注入。
CASE WHEN 注入
Case when 的用法: 一旦满足了某一个WHEN, 则这一条数据就会退出CASE WHEN , 而不再考虑 其他CASE;
Case函数(Case搜索函数): 判断表达式的真假,如果为真,返回结果;如果为假,返回else值;如果未定义else值,则返回空值(使用条件确定返回值);
通过使用 case when 语句可以将 order by 后的 orderExpression 表达式中添加 select 语句。(前提是必须存在order by)。
case when
(select substr(ip,{0},1)='{1}'
from servers where hostname='webgoat-prd')
then hostname else mac end".format(i, char)
JWT( JSON Web Token )
概述
JSON Web 令牌是一种跨域验证身份的方案。JWT 不加密传输的数据,但能够通过数字签名来验证数据未被篡改。JWT 分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。JWT 的内容以 Base64URL 进行了编码。
实现流程
- 第一次登陆发送账号密码到服务器
- (确认登录信息正确后)服务器生成 JSON 头部和声明,将登录信息写入 JSON 的声明中(通常不应写入密码,因为 JWT 是不加密的),并用 secret 用指定算法进行加密,生成该用户的 JWT。此时,服务器并没有保存登录状态信息。
- 服务器将 JWT(通过响应)返回给客户端
- 用户下次会话时,客户端会自动将 JWT 写在 HTTP 请求头部的 Authorization 字段中
- 服务器对 JWT 进行验证,若验证成功,则确认此用户的登录状态
- 服务器返回响应
组成
头部 (Header)
{
“alg”:“HS256”, // 签名使用的算法的参数
“typ”:“JWT” // token 的类型为 JWT
}
声明(Claims) Payload(有效载荷)
携带存放的数据 用户名称、用户头像之类 注意敏感数据
JWT 固定参数(标准中注册的声明 (建议但不强制使用))
- iss:发行人
- exp:到期时间
- sub:主题
- aud:用户
- nbf:在此之前不可用
- iat:发布时间
- jti:JWT ID 用于标识该 JWT
签名(Signature)
服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密码进行加密,生成的字符串就是 JWT 的签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
base64UrlEncode(your secret)
)
签名就是base64编码的 头部,声明与服务器的密钥用头部标注的算法得到的
攻击手段
-
伪造
无密钥(服务器无验证):修改alg为none,删除签名
有密钥:直接修改payload,重新签名 -
爆破
针对密钥爆破,爆破加密得到的结果与原签名对比得到密钥 -
配合
jwt存在其他参数传递过程,配合一些其他的漏洞。
检测
- javaweb一般都有jwt
- 查看 HTTP 请求头部的 Authorization 字段
- 查看请求数据包中有无token,token格式很好辨认,以点分隔。