作者 | Michele Riva
Facebook 上有一个名为“Il Programmatore di Merda”(翻译为“ The Shitty Programmer”,中文含义为“糟糕的程序猿”)的社区, 我经常去浏览。网站经常分享一些糟糕的代码和有关编程的话题。今天,我看到一段令我难以置信的代码:

本周最烂代码

仔细看看,上面的代码错误太多,以至于我不知从何谈起。
如果你是一个初级开发工程师,这篇文章会帮你明白上述代码中存在的一些非常严重的问题,并让你引以为鉴。

1

28 行错误代码
我把上面的代码摘录下来,以便我们进行后面的讨论:

一时之间,我竟不知道从何说起。
上述错误大致分为 3 类:
安全问题

基本编程概念问题

代码格式化问题

2

安全问题
我们非常确定以下代码会在客户端运行,因为它被包装在两个

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: 1 }); 所以按照代码的意思,作者使用 jQuery 设置 cookie,让该 cookie 告知 Web 应用程序用户是否通过身份验证。 好吧,千万不要使用 JavaScript 来设置此类 cookie。 如果你有存储此类登陆信息的需求,那么使用 cookie 确实是最常见的解决方案,这没有什么问题!但是使用 JavaScript 设置它们意味着你无法设置httpOnly属性,这会导致每个恶意脚本都能轻而易举地访问和获取你的 cookie 内容。 是的,我知道,他们只是存储'loggedin': 'yes'的键值信息,可能不是上面我讲的那种情况,但总之这是一个糟糕的做法。 另外,打开 Chrome 控制台,我随时可以输入.cookie(′loggedin′,′yes′,expires:1);所以按照代码的意思,作者使用jQuery设置cookie,让该cookie告知Web应用程序用户是否通过身份验证。好吧,千万不要使用JavaScript来设置此类cookie。如果你有存储此类登陆信息的需求,那么使用cookie确实是最常见的解决方案,这没有什么问题!但是使用JavaScript设置它们意味着你无法设置httpOnly属性,这会导致每个恶意脚本都能轻而易举地访问和获取你的cookie内容。是的,我知道,他们只是存储′loggedin′:′yes′的键值信息,可能不是上面我讲的那种情况,但总之这是一个糟糕的做法。另外,打开Chrome控制台,我随时可以输入 .cookie(‘loggedin’,‘yes’,{expires: 1000000000000})命令, 而且即使我没有用户帐户,也会永远保持登录状态。

3

基本编程概念问题
想说的话太多,但无奈时间有限。
很明显,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) {
KaTeX parse error: Expected 'EOF', got '}' at position 40: …ogInFailed); }̲ }); 使用 jQuery … .cookie(‘loggedin’,‘yes’,{expires:1}); 保持认证一整天,甚至都不需要一个帐户。
所以,这个网站到底是怎么确定我是谁的?也许它只是通过用户名 / 密码身份验证显示一些私人内容,所以它没有展示任何个人数据。总之,没有人知道代码为什么会这么写。

4

代码格式化问题
代码格式可能是整个代码中不太重要的部分,但我们可以很容易地判断出该开发人员复制 / 粘贴了某些网站上的代码。
下面的代码片段,我们可以看到开发者使用了双引号引用字符串:
var username = $("#username").val();
var password = $("#password").val();
然而,下面的代码却又使用了单引号字符串:

$.cookie(‘loggedin’, ‘yes’, { expires: 1 });
这些看起来可能没有那么重要,但实际上我们可以确定,开发人员可能已经从 StackOverflow 复制粘贴了一些代码,甚至都没有遵循整个代码库的代码规范来重写它们。当然,这只是一个小问题,但它表明开发人员并不真正关心和理解代码的工作方式,只是希望代码以某种方式工作。
大家不要误会,我每天都会在 Google 上进行搜索,但比起仅仅复制和粘贴代码来实现功能,理解代码的工作原理——比如理解如何设置 Cookie,实际上更为重要。如果由于某种原因整个进程中断了怎么办?你如何确定是脚本的哪一部分不起作用呢?

5

总结
我绝对可以确定上面的代码是伪造的。这是我第一次看到使用同步方式进行 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!

6

后记
我在 Reddit 对此进行了一番讨论后,一个非常给力的小伙伴分享了下面的 Reddit 话题:
“This JavaScript code powers a 1,500 user intranet application”
https://www.reddit.com/r/programminghorror/comments/66klvc/this_javascript_code_powers_a_1500_user_intranet

所以,是我错了。这段代码并不是伪造的!

原文链接:

https://www.micheleriva.it/posts/2020-07-31-reviewing-the-worst-piece-of-code-ever

审阅史上“醉”烂的代码~相关推荐

  1. 史上最烂代码_历史上最大的代码库

    史上最烂代码 Here's a diagram of the biggest codebases in history, as measured by lines of code: 这是历史上最大的代 ...

  2. Maven——Maven核心概念——史上最烂系列

    Maven 是目前最流行的自动化构建工具,对于生产环境下多框架.多模块整合开发有重要作用.Maven 是一款在大型项目开发过程中不可或缺的重要工具.(自己粗略写了一个SSM项目之后,回顾头来看这个,会 ...

  3. SpringClound——SpringClound入门概述——史上最烂

    SpringClound--微服务概述--史上最烂 SpringClound--SpringClound入门概述--史上最烂 SpringCloud--Eureka--史上最基本 SpringClou ...

  4. 德国电信撕逼诺基亚:史上最烂5G供应商

    德国电信Telekom声称诺基亚Nokia是史上最烂5G供应商,不过还是给了诺基亚一个机会. 德国电信要求诺基亚提供更好的服务和产品.据其内部文件说,只有当诺基亚有所改进时,才有做欧洲5G网络的供应商 ...

  5. 史上最烂开发项目,开发整整12年!负责人还进了监狱!

    点击上方"Python大本营",选择"置顶公众号" python大本营  IT人的职业提升平台 文章来自:程序员(ID:imkuqin)猿妹编译 原文:http ...

  6. 史上最坑爹的代码!个个让人崩溃!

    本文整理自:开源中国 | 码云 Java 就是这么一门神奇的语言,任何水平的人都能写出可以运行的代码,但是一看代码便知水平高低.作为一个程序员,你看过哪些坑爹代码,你又写过多少坑爹代码,还有多少你不知 ...

  7. 史上最强c++代码——“boost::asio”

    在C++编程领域,有一段备受推崇的代码--"boost::asio",它被认为是世界上最强大的C++代码之一.它是一个跨平台的网络编程库,提供了异步I/O.TCP/UDP套接字.定 ...

  8. 伦敦奥运会:史上最贵,史上最烂

    英<独立报>:牛津大学商学院称伦敦奥运会直接成本84亿英镑,涉及安保.交通.开闭幕式及场地建设,为奥运史最为昂贵,贵得出奇.这还没计算上相关基础设施建设耗费的间接成本.讽刺的是,史上最贵的 ...

  9. 史上最烂的项目:苦撑 12 年,600 多万行代码!

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来源:http://tinyurl.com/y55d23p4 转自:程序IT圈 这项目 ...

  10. 我的天!史上最烂的项目:苦撑12年,600多万行代码...

    编译:欧剃 来源:projectfailures.wordpress.com 你见过最烂的项目,撑了多长时间才完蛋?六个月?一年?今天介绍的这个奇葩项目,不但一开始就烂得透透的,还硬撑了12年多,直到 ...

最新文章

  1. 关于锁机制:数据库锁
  2. 百度地图- - - 鹰眼轨迹- - - -实时定位
  3. 吴恩达机器学习(第三章)——线性代数回顾
  4. java接口有非抽象方法_[Java教程]纳尼,java可以在接口中实现非抽象方法了?
  5. 高级数据结构与算法 | 回溯算法(Back Tracking Method)
  6. linux笔记之 rpm常用参数 ,yum安装编译器,httpd服务的开关
  7. webstorm环境安装配置(less+autoprefixer)
  8. spark将rdd转为string_八、Spark之详解Tranformation算子
  9. python图书馆预约系统_python实现图书馆研习室自动预约功能
  10. POJ 2243:Knight Moves(双向BFS)
  11. Python(五):list、tuple
  12. 借助创客匠人玩转视频号
  13. soui 设置边框_第四篇:SOUI资源文件组织
  14. 随笔-Python批量调整图片大小
  15. 12星座大全 ^__^
  16. 根据六边形边长求六边形面积
  17. 【编写自己的RTOS】搞定任务调度
  18. Java架构师成长之路
  19. 我的CSDN博客正式登陆
  20. Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】

热门文章

  1. SAP MM-MB52 物料库存查询简单操作
  2. U8 用友 ERP 库存查询SQL
  3. 安装和使用Entrez Direct
  4. 软件定义网络入门学习笔记3-学习第一个ryu app-simple_switch_13.py
  5. Word标题中按级别自动添加编号
  6. html5游戏cps,15字讲清CPC、CPM、CPA、CPS、CPL…没节操了
  7. matlab 张正友工具箱,TOOLBOX_calib0 张正友的标定工具箱,直接运行会有错误,这是经过修改的 首先 _gui,确 matlab 238万源代码下载- www.pudn.com...
  8. 如何将计算机恢复到桌面快捷方式,怎样还原电脑系统默认的Windows快捷方式及其图标呀?...
  9. java微信开发页面清除缓存,h5清理微信浏览器网页缓存
  10. NPN与PNP型传感器的区别