Facebook 上有一个名为“Il Programmatore di Merda”(翻译为“ The Shitty Programmer”,中文含义为“糟糕的程序猿”)的社区, 我经常去浏览。网站经常分享一些糟糕的代码和有关编程的话题。今天,我看到一段令我难以置信的代码:
本周最烂代码
仔细看看,上面的代码错误太多,以至于我不知从何谈起。
如果你是一个初级开发工程师,这篇文章会帮你明白上述代码中存在的一些非常严重的问题,并让你引以为鉴。
我把上面的代码摘录下来,以便我们进行后面的讨论:
<script>
function authenticateUser(username, password) {
var accounts = apiService.sql(
"SELECT * FROM users"
);
for (var i = 0; i < accounts.length; i++) {
var account = accounts [i];
if (account.username === username &&
account.password === password)
{
return true;
}
}
if ("true" === "true") {
return false;
}
}
$('#login').click(function() {
var username = $("#username").val();
var password = $("#password").val();
var authenticated = authenticateUser(username, password);
if (authenticated === true) {
$.cookie('loggedin', 'yes', { expires: 1 });
} else if (authenticated === false) {
$("error_message").show(LogInFailed);
}
});
</script>
一时之间,我竟不知道从何说起。
上述错误大致分为 3 类:
我们非常确定以下代码会在客户端运行,因为它被包装在两个<script>
标记间(当然,它使用 jQuery 编程框架)。不要误会我的意思,这些代码即使是运行在服务器端也很糟糕,在客户端上运行这些代码会将你的数据库暴露给……每个人。
让我们先看一下authenticateUser
函数:
function authenticateUser(username, password) {
var accounts = apiService.sql(
"SELECT * FROM users"
);
for (var i = 0; i < accounts.length; i++) {
var account = accounts [i];
if (account.username === username &&
account.password === password)
{
return true;
}
}
if ("true" === "true") {
return false;
}
}
我们的代码在某些地方有个叫做apiServices
的接口,它公开了一个.sql
方法,可以对数据库进行 SQL 操作。这意味着,如果你在运行上述代码的浏览器上打开控制台,就可以执行各种查询,安全隐患极高。比如,你无需获得授权就可以这样做:
apiService.sql("show tables;");
调用上述 API,代码执行后会返回数据库的所有表名称。
我们暂且假装这不是一个严重的问题。但是请接着往下看:
if (account.username === username &&
account.password === password)
所以,作者的意思是直接保存了用户所有的明文密码,而没有对它们进行哈希处理?
这简直不可思议!现在我可以打开 Chrome 浏览器的调试器,直接查看每个用户的明文密码。
我非常确定,很大一部分用户会在社交网络、电子邮件服务、银行账户等服务中使用相同的用户名和密码,想象一下,别人可以在没有任何障碍下就可以拿到你的账户和密码,这得有多可怕。
作者尝试设置登录
cookie 的方式也存在问题:
$.cookie('loggedin', 'yes', { expires: 1 });
所以按照代码的意思,作者使用 jQuery 设置 cookie,让该 cookie 告知 Web 应用程序用户是否通过身份验证。
好吧,千万不要使用 JavaScript 来设置此类 cookie。
如果你有存储此类登陆信息的需求,那么使用 cookie 确实是最常见的解决方案,这没有什么问题!但是使用 JavaScript 设置它们意味着你无法设置httpOnly
属性,这会导致每个恶意脚本都能轻而易举地访问和获取你的 cookie 内容。
是的,我知道,他们只是存储'loggedin': 'yes'
的键值信息,可能不是上面我讲的那种情况,但总之这是一个糟糕的做法。
另外,打开 Chrome 控制台,我随时可以输入$ .cookie('loggedin','yes',{expires: 1000000000000})
命令, 而且即使我没有用户帐户,也会永远保持登录状态。
想说的话太多,但无奈时间有限。
很明显,authenticateUser
函数写的就是一堆垃圾,该函数的实现充分表明作者缺乏一些基本的编程概念。
function authenticateUser(username, password) {
var accounts = apiService.sql(
"SELECT * FROM users"
);
for (var i = 0; i < accounts.length; i++) {
var account = accounts [i];
if (account.username === username &&
account.password === password)
{
return true;
}
}
if ("true" === "true") {
return false;
}
}
代码作者为什么不只查询给定用户名和密码的用户,而是检索出数据库中的所有用户呢?如果该数据库中拥有数百万个用户怎么办?
还有前面我已经说过了,在这里我再提一下,为什么作者不对数据库中的明文密码进行哈希处理?
让我们接着看一下authenticateUser
函数的返回值。
我们可以看到,该函数接收两个 string 类型的参数,最后返回一个布尔类型的值。所以,下面的代码即使很糟糕(明文密码),但也有一定的意义:
for (var i = 0; i < accounts.length; i++) {
var account = accounts [i];
if (account.username === username &&
account.password === password)
{
return true;
}
}
上面代码的含义很清楚,“是否存在具有 X 用户名和 Y 密码的用户?是的,所以函数执行结果返回 true”。
但是下面这个代码:
if ("true" === "true") {
return false;
}
这根本没有任何道理呀。
为什么该函数不去掉always-true
条件判断,直接返回 false?
现在,我们继续接着分析后面的代码:
$('#login').click(function() {
var username = $("#username").val();
var password = $("#password").val();
var authenticated = authenticateUser(username, password);
if (authenticated === true) {
$.cookie('loggedin', 'yes', { expires: 1 });
} else if (authenticated === false) {
$("error_message").show(LogInFailed);
}
});
使用 jQuery 获取属性值的代码部分没有什么问题。问题在于它如何处理loggedin
用户的 cookie。
我们之前讨论过这样一个问题,我可以在我的 Chrome 控制台输入$ .cookie('loggedin','yes',{expires:1});
保持认证一整天,甚至都不需要一个帐户。
所以,这个网站到底是怎么确定我是谁的?也许它只是通过用户名 / 密码身份验证显示一些私人内容,所以它没有展示任何个人数据。总之,没有人知道代码为什么会这么写。
代码格式可能是整个代码中不太重要的部分,但我们可以很容易地判断出该开发人员复制 / 粘贴了某些网站上的代码。
下面的代码片段,我们可以看到开发者使用了双引号引用字符串:
var username = $("#username").val();
var password = $("#password").val();
然而,下面的代码却又使用了单引号字符串:
$.cookie('loggedin', 'yes', { expires: 1 });
这些看起来可能没有那么重要,但实际上我们可以确定,开发人员可能已经从 StackOverflow 复制粘贴了一些代码,甚至都没有遵循整个代码库的代码规范来重写它们。当然,这只是一个小问题,但它表明开发人员并不真正关心和理解代码的工作方式,只是希望代码以某种方式工作。
大家不要误会,我每天都会在 Google 上进行搜索,但比起仅仅复制和粘贴代码来实现功能,理解代码的工作原理——比如理解如何设置 Cookie,实际上更为重要。如果由于某种原因整个进程中断了怎么办?你如何确定是脚本的哪一部分不起作用呢?
我绝对可以确定上面的代码是伪造的。这是我第一次看到使用同步方式进行 SQL 查询:
var accounts = apiService.sql(
"SELECT * FROM users"
);
通常,我希望查询功能的实现类似下面这样:
var accounts = apiService.sql("SELECT * FROM users", (err, res) => {
console.log(err); // some error
console.log(res); // query result
});
或者这样:
var accounts = await apiService.sql(
"SELECT * FROM users"
);
即使使用同步方式调用apiService.sql
返回查询值(我对此表示怀疑),在内部也必须进行与数据库的连接、执行查询语句并发送返回查询结果,这些过程(你可能已经知道了)明显是不同步的。
但是,即使上面的代码不是伪造的,我也可以确信它是由初级开发人员编写的。我刚刚开始入行写代码的一段时间里,我很确定自己为之前的公司也写过这么糟糕的代码。
这个锅不能甩给初级开发人员。
让我们假设上面的代码是真实的。这里的初级开发人员正在竭尽所能实现功能。他 / 她尚未开始学习如何正确处理 SQL 查询、cookie 以及其他需要注意的技术点,这完全可以理解!
高级开发人员应该提供某种形式的指导,以确保初级开发人员可以理解他们的错误,保证这样的错误代码不会在生产环境中使用。
我也可以确认,有些公司其实并不真正在乎开发人员编写的代码质量。
代码能解决问题吗?——生产环境部署一下就知道了呀。代码是由初级开发人员编写的,甚至都没有高级开发人员的批准吗?——部署运行一下就知道结果了呀。
哎,Shit happens!
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/NcMXhf7y3D8XnEoo47GWOw
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。