记录: 一次解决整型溢出攻击(使用scala,隐式转换)
最近项目遇到一次整型溢出攻击
有一个功能,玩家购买num个物品. 每个物品花费14货币. 客户端限制玩家只能购买 1-9999个该物品.
但是某玩家通过技术手段,获得了客户端的运行权限. 于是发送协议购买该物品 306783379 个
于是服务器收到请求进行以下处理
val num = message.getInt("num") //获得客户端发送来的 306783379
val cost = num * produc.price //这里没有校验物品的数量就直接计算总价了. 所以总价是 306783379 * 14
调用扣除货币数量 cost
调用发放物品数量 num
这一眼看起来没什么问题, 但是扣除时发现只扣除了他 10货币. 猛然发现 num是int型的,所以 int 306783379 乘以14后溢出了, 结果是10
再查发现代码里非常多地方有这种直接是 num * price的, 于是想以最小的改动来封禁这个bug.
最开始的想法是写一个函数, 参数是相乘的2个数, 如果越界就抛异常. a * b 改为 Util.safeMultiple(a, b) 但发现这么改代码看起来有点蛋疼. 后来决定使用隐式转换
定义个IntChecker ,和implicit 类SafeInt,
package thomaswong025.example1 /**
* Created by Administrator on 2018/1/9/009.
*/
object IntChecker {
implicit class SafeInt(val a: Int){
def `safe*`(b: Int) = {
val r = BigDecimal(a) * b
if (r.isValidInt) r.toInt else throw new RuntimeException(s" $a * $b out of int range")
}
}
}
做个测试:
package thomaswong025.example1
import thomaswong025.example1.IntChecker._
object Test {
def main(args: Array[String]) {
val a = 306783379
val b = 14
println(a * b) //输出10
println(a `safe*` b) //抛异常
}
}
找到其他需要使用安全乘法的地方 把乘号改成 `safe*`, 记得在顶部import 包路径.IntChecker._即可
如果需要安全加减等操作,也可以直接自己在SafeInt类里加上 注意: 改成 `safe*` 后, 函数优先级比原来的 * 降低了, 跟其他函数调用的优先级一样. 所以 如果代码里有 a * b / c 变成 a `safe*` b / c 之后, 一定要记得加括号 (a `safe*` b) / c
记录: 一次解决整型溢出攻击(使用scala,隐式转换)的更多相关文章
- CVE-2018-14634 - Linux create_elf_tables()中的整型溢出 - 翻译
原文:https://seclists.org/oss-sec/2018/q3/274 摘要 Qualys研究实验室的安全团队发现一个位于Linux内核函数create_elf_tables()中的整 ...
- C语言的整型溢出问题
整型溢出有点老生常谈了,bla, bla, bla… 但似乎没有引起多少人的重视.整型溢出会有可能导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,比如最近OpenSSL的heartbleed事件,就是一 ...
- Linux漏洞分析入门笔记-CVE_2018_6323_整型溢出
操作系统 Ubuntu 16.04 /32 位 调试器 IDA pro 7.0 漏洞软件 binutils-2.29.1 0x00: 漏洞描述 1.什么是整数溢出: 在计算机中,整数分 ...
- c语言之——整型的隐式转换与溢出检测
溢出检测 我们可以通过下面的方式来检测溢出: if(a > INT_MAX - b) { printf("overflow\n"); } 我们利用整型的最大值减去其中 ...
- dateline 在数据库中就是 整型字段。date函数是可以转换成可读日期的。
返回数据中的dateline全部用date()函数转换后再返回,是要嵌套循环还是遍历,代码怎么写? //查询我的活动 function user_activity_info_by_uid($uid){ ...
- 一个 MySQL 隐式转换的坑,差点把服务器整崩溃了
我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 本来是一个平静而美好的下午,其 ...
- 工作总结 无法确定条件表达式的类型,因为“<null>”和“System.DateTime”之间没有隐式转换 解决办法 object——Nullable<T> (可空类型)
可空值类型 备注 一种类型认为是可以为 null,如果它可以分配一个值,也可以分配null,这意味着类型具有无论如何没有值. 默认情况下,所有都引用类型,如String,是否可以为 null, ...
- 无法确定条件表达式的类型,因为“<null>”和“System.DateTime”之间没有隐式转换----解决办法
例子:(报错了) public DateTime? time { get; set; } time = item.HospOutDate.HasValue ? DateTime.Parse(item. ...
- Spark记录-Scala程序例子(函数/List/match/option/泛型/隐式转换)
object func { def main(args:Array[String]):Unit={ //函数赋值给变量时, 必须在函数后面加上空格和下划线. def sayHello(name: St ...
随机推荐
- 笔记1 python入门学习笔记
目录 官方手册 菜鸟站手册地址: python的运行方法 注释 小技巧: input()接收用户输入的内容(默认为字符串) print() 运算符 is 是判断两个标识符是不是引用自一个对象 all和 ...
- K-th Number POJ - 2104
K-th Number POJ - 2104 You are working for Macrohard company in data structures department. After fa ...
- 为什么要用枚举实现Singleton--Java
原文地址:http://www.cnblogs.com/AprilCal/p/5426007.html 理由一:无需再考虑可序列化的情况 <effective java>第77条:对于 ...
- Android stadio 调试太掉了
1.evalute expresstion 可以看任何变量的任何属性,就算是一个字符串url,你可以url.length(),你不用输入完就有提示.对象的方法有提示! 2.调试技巧 就是当一行里面有很 ...
- 踩坑 Uncaught RangeError: Maximum call stack size exceeded
今天遇到了一个错误, 堆栈溢出,很好奇就是一个简单ajax请求怎么会报这个错误,研究了一下,发现犯了一个很低级的错误,data的参数错误了: passWord是未定义的变量,值为空,然后导致了这个问题 ...
- Leetcode 639.解码方法2
解码方法2 一条包含字母 A-Z 的消息通过以下的方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 除了上述的条件以外,现在加密字符串可以包含字符 ' ...
- 动态规划--找零钱 coin change
来自http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/ 对于整数N,找出N的所有零钱的表示.零钱可以用S={s1,s ...
- SQLSERVER 数据库基础操作
1.修改表中字段的长度,类型为varchar,从30改到50 语句执行(注:当前为30): alter table 表名 alter column 列名 varchar(50) 2.增加 ...
- 【转】 [UnityUI]UGUI射线检测
http://blog.csdn.net/lyh916/article/details/50947026 1.Graphic Raycaster 主要用于UI上的射线检测,挂有这个组件的物体,必须要挂 ...
- 【转】Apache Thrift - 可伸缩的跨语言服务开发框架
Apache Thrift - 可伸缩的跨语言服务开发框架 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Java 开发人员角度详 ...