一位客户要求我重新设计他们的网站,这是另一位顾问开发的ASP.NET Webforms应用程序。这似乎是一个相对简单的工作,但是在查看了代码之后,显然并非如此。

此应用程序的编写不正确。完全没有它极易受到SQL注入攻击的影响,业务逻辑散布在整个应用程序中,重复很多,无用的死代码无济于事。最重要的是,它不断抛出令人窒息的异常,因此网站似乎运行正常。

我的工作是简单地更新HTML和CSS,但是许多HTML是在业务中生成的逻辑,这将是一场噩梦。我对重新设计的估计超出了客户的预期。他们问为什么要这么久。

我如何向我的客户解释这段代码有多糟糕?在他们看来,应用程序运行得很好,重新设计应该是一次性的。这是我对前任顾问的反对。我如何给出非技术性客户可以理解的简单而具体的示例?

更新

感谢所有答复。
SQL注入攻击演示使感觉,我将在测试环境中进行演示。
这只是此应用程序中许多问题的一部分。我一直在寻找方法来解释为什么其他部分(例如,在数据层中生成html)
需要用更好的实践来替换,以便进行html和css更新。
这里有很多很好的建议,当我与客户交谈时,我会把它们拼凑起来。

评论

演示SQL注入攻击吗?

该应用程序编写得不好。完全没有他们几乎从来没有。 :)

除了像奥斯丁所说的那样展示问题。不要低估白板和记号笔的功能。大多数人对以图片形式解释的错误设计都反应良好。

如果不大,请重写-如果不大,请不要接受

客户说重新设计,他们认为是HTML / CSS。我会使用术语“缺乏模块化”,并强调“逻辑设计”与“表示”。建筑结构的隐喻是有用的。为了改变客厅的外观,我不得不进入空调系统。在好的模块化设计中,不会发生这种情况。

#1 楼

非技术人员不是白痴(在大多数情况下)。如果您保持足够高的水平,他们可以理解技术论点。选择一个您认为应该很简单的任务,并逐步说明为什么它并非如此。


我希望此更改在一个文件中成为一个单词。
最可能更改它的地方似乎是在这里,但是当我在此处进行更改时,它仅在一个地方起作用,而这使其他7个地方中断了。当我
修复一个位置时,它又摔坏了两个地方,引起了多米诺骨牌效应,所以我认为应该花10分钟进行一次更改就导致花了2个小时。
这只是一个例子。还有更多意想不到的2小时任务。


评论


鉴于存在大量错误报告的内容,“它打破了__更多地方”确实似乎是描述多米诺骨牌效应的最佳方法...

–伊兹卡塔
2012年11月13日在3:37



是的,我会在时间和成本之间建立更多的联系。向他们显示您期望成本变化的金额与最终导致成本变化的金额。根据我的经验,除非您能证明他们的支出是其他支出的两倍,三倍或更多,否则客户很少会注意。

–蒂姆·奥布莱恩(Tim O'Brien)
2012年11月19日在18:18

#2 楼

代码结构,样式,技术债务是一回事-至少在最初,直到客户信任您之前-您将不得不忍受。

安全漏洞是另一回事。

就个人而言,我会根据使用现有结构和样式所需的工作进行估算,同时要明确代码库存在重大问题。我将单独提出安全隐患:在会议上演示数据库中的黑客攻击,以使问题归宿。

我很高兴与以前的客户使用忠诚礼品卡系统进行此操作,当时我在“我的”卡上放了5000英镑,并让他检查了自己的储物柜。

评论


+1演示SQL注入攻击的严重程度。在他们面前做。如果可能,请录制视频以记录他们的反应。

–菲利普
2012年11月12日17:36

@Philip:...该演示最好应在该应用程序的独立开发环境中。清除他们的生产数据库将证明这一点,但可能会丢失您的合同(并提起诉讼)。

–FrustratedWithFormsDesigner
2012年11月12日18:15



@FrustratedWithFormsDesigner,如果他们甚至有可用的开发环境...

–棘轮怪胎
2012年11月12日19:30



@FrustratedWithFormsDesigner:当然,不建议擦除数据库,无论它多么容易和生动。但提取私人数据,然后(小心地)更改一些金额(例如@Michael制作的礼品卡上的余额),可能对他们来说同样令人惊讶。对于额外的要点,显然您不需要看代码。首先转储表列表,选择一些有趣的名称,然后转储内容。如此脆弱的观点应该花不了太多。

–哈维尔
2012年11月13日15:09

#3 楼

这里有一些关于如何传达和传达给客户的很棒的建议。希望他们能为您带来回报。

这里是一个大红色的标志!

如果客户要求您不要做出除您同意的内容以外的任何更改(HTML和CSS)我将继续进行此项目并撤回投标。

即使对所有缺陷和安全性问题进行了书面和充分沟通的概述,对于我来说,潜在的责任也实在太大了。舒服。即使客户在遭到黑客入侵或破坏后从未采取任何法律行动或要求修复;您的名字和声誉仍然与作品息息相关。

您可能会损失远远超过获得的收益。

评论


+1用于查看更宽的图像。如果您处理它并说您已完成,则即使您仅继承了它们,也可能会对错误和安全问题承担一些责任。如果有人操纵了我的刹车,而机械师修理了我的自行车,只是解决了问题,我可能还会考虑起诉他们。

–sleske
2012年11月13日在8:05

+1这是一堂课的顾问,学习时间太长(而且,在经济不景气的情况下,要承认这一点很困难)。专业知识的价值既取决于您所做的工作,也取决于您拒绝的工作。

–蒂姆·奥布莱恩(Tim O'Brien)
2012年11月19日在18:19

+1这是我学到的艰辛教训,因此我的第一笔生意差点倒闭。在这些情况下,列出所有“缺陷”并报价以解决这些问题的成本通常要比客户愿意支付的精力更多。

–卡塔尔兹
13年2月10日在12:41

#4 楼

解释并可能证明该缺陷。
当您对他说脏话时,就他们而言,您所说的一切可能只是热闹的。一旦向他们展示了如何通过SQL注入滥用他们的应用程序,那么您就突然成为一个值得信赖的人。您需要信誉才能重新谈判。这足以改变游戏规则,可以给您。

对您的前任表示慈善
这并不意味着假装错误不存在,但是如果您遇到居高临下的人,那么你就会失去信誉。除了可能给他带来疑问的好处外,不要对程序员说一句话。专注于代码,而不是编码器。让他们觉得您是“好人”会给您更多的谈判余地。 “好人”从不说卑鄙的话。在向客户端解释现有的安全错误(例如SQL注入漏洞)时,我更喜欢这样说:Web应用程序安全性是一个快速发展的领域。人们甚至在今天仍学习的许多开发工具和技术都是在对大多数漏洞利用方法进行充分理解之前发展起来的。为了保持领先的安全性,您必须密切关注该领域,有时甚至更改您的整个开发风格。大多数程序员都不这样做。


我们走了。没有关于开发商的恶意话;他只是“大多数程序员”,这意味着他在相当不错的公司中。现在,您已经证明您不是“大多数程序员”,这给了您更多的信誉,也可能是他们为您支付更多钱的原因。
谈判新的安排
一旦客户了解到自己的应用程序可以被公众滥用,他将希望对其进行修复。您可能是他要问解决此问题的人。您可能会或可能不会想要这份工作,因此在与他们交谈之前,请仔细考虑。

至少,您希望有更多时间完成他们已经给您的工作。您已经为他们设置了足够的措手不及的漏洞,以至于他们可能无法使您达到最初的估计。但是请确保客户知道您的身份,并且不会因为这种安排而将其修复。

通常,开发人员(您)通常希望从头开始重做整个事情。在这种情况下,这甚至可能是一个选择。但是即使那样,客户仍然需要一些可以使他的业务保持运转的东西,直到构建新应用为止。这意味着即使您从头开始,也可能仍需要对旧应用程序进行一些更新。

评论


+1永不屈居。让事实说明一切...

–sleske
2012年11月13日在8:11

为“对您的前任感到慈善” +1。

–麦桑福德
2012年11月13日15:36

#5 楼

我以评论开始,因为起初我以为是一旁,但实际上可能不是。

我会充分记录您认为应该重新设计的所有内容,以及为什么(为什么?如果他们不进行更改,则会发生),并提供解决此问题的估算值。对于您认为有安全隐患的任何事情,我都会格外谨慎。

我会在触摸任何代码之前进行此操作,并确保您的客户拥有此报告的副本,最好带有某种时间戳记。这可能需要一些时间,但是如果其中一种安全风险得以实现,它也将为您提供帮助。更好的是,如果您可以得到表明他们已收到文档的签名。

当然,您可以指向继承的原始代码的源代码管理,如果确实发生的话,那么它将更容易指向此文档,然后以更专业的方式说:“看?我告诉过你。”

该文档可以作为进一步讨论的出发点,甚至可以由您的客户使用让“合适的人”允许进行部分或全部更改。

话虽如此,一旦客户不理解风险,如果他们表示愿意做这项工作,就要咧嘴并承担无论如何,还是走开。

评论


希望他们实际上正在使用源代码控制。

–伯纳德
2012年11月12日21:30

好答案。但是,由于曾因类似情况(包括完整的文档和客户签字)而向法院提起诉讼,因此我仍然要花很多钱和头疼。

–史蒂夫
2012年11月12日23:32

原则上讲是个好主意-但是,请注意,这可能需要大量工作。这可能仅适用于大型工作,否则,您将花费50个小时来记录一项仅能支付20费用的工作的问题。

–sleske
2012年11月13日在8:07

@sleske:同意将进行大量工作,但如果发生最坏情况并且存在安全漏洞,希望也能对您有所帮助。至少,您需要说明您看到安全风险并且不想对这些预先存在的风险负责的内容。

–旺角桑科
2012年11月13日14:24

@WonkotheSane:是的,但只有在您接受项目后才能这样做。如果问题很大,而您的计划工作很小,那么最好拒绝该项目。当然,您仍然应该记录您的顾虑(安全性和其他方面),但是,如果您从未从事过该项目,那么就不会有承担责任的风险。最终,您必须衡量您的客户是否愿意支付清理费用。

–sleske
2012年11月13日14:27

#6 楼

请记住,客户端会在维护他们的应用程序时向您寻求帮助。指出您对其应用程序发现的任何问题是您的专业工作。客户可能不知道这些问题是否存在,应该让他们知道。以他们可以理解的方式解释这些问题,并让他们决定如何进行。

使用真实的示例来说明这些问题,例如汽车抛锚或需要维修的洗衣机。重点是使用他们已经熟悉的示例。为了解释SQL注入,我仅演示一下这是什么以及为什么它是问题。

最后,您要传达的是,您关心被要求处理的应用程序的成功。

评论


这完全不是一辆故障车,除非该车是由业余机械师用随机零件制造的。这就像一个无能的承包商建造的车库,业主希望OP放入自动开门器。 OP发现车库不安全,需要立即进行大修。

–kevin cline
2012年11月12日20:07



想象一下一辆故障车,它使用胶带将零件固定在一起,并使仪表板无法向驾驶员显示任何警报或警告,而方向盘随时可能掉落。这需要一些创造力,但是可以使用不同的类比来说明问题。

–伯纳德
2012年11月12日20:13

或注意“定制”的缠绕麻绳加速器电缆,您可以将其绑在控制台上以进行手动加速。.“电传飞行”技术便宜。他们在“红色绿色秀”上所做的一切都可能适用。他们拥有的是“有效的”工具,但它并不漂亮,经过粗略的检查,它似乎很脆弱并且放大了任何更改的风险。

– JustinC
2012年11月12日在21:47



如果我可以为此增加额外的票数,那纯粹是“记住客户会在维护他们的应用程序时向您寻求帮助”。

–丹尼尔·霍林拉克(Daniel Hollinrake)
2012年11月15日上午10:21

#7 楼

我喜欢使用客户可以关联的类比。我为赢得这份工作而预先投入的工作量将取决于客户打算花费的金额(100美元与20,000美元相差甚远)。注意我说“打算”。如果您没有得到所要的东西,那么您对所涉及的价值的个人估计并没有多大意义。

根据您的情况-再次取决于金钱-我可能会画一条线从两面走出来,然后对客户说:“这就是您现在对软件进行可视化的方式。数据从一端出来,从另一端出来,看起来都很漂亮,干净,简单”。 “这就是您认为软件在内部的外观”,然后绘制第三条线,将框内的两条线连接起来。

然后,我将画一个盒子,就像第一个盒子一样,外面的输入和输出线在外面,除了这次我要说的是:“这就是软件现在盒子里面的样子。 ”然后这次将两条线连接起来,我会随机绘制一堆意大利面条,可能带有断点,连接点和涂鸦。

最后我会说,“现在你在问我什么要做的就是...”,然后在第一个框内画一个简单的形状,也许是一个小半圈碰到线,然后说“但要做到这一点,我就必须这样做...”并画出一个龙卷风外观围绕线呈螺旋状,然后继续...“以便绕过所有这些...”,然后指向另一个盒子中的意大利面。

我认为这会推动在大约2分钟的时间内回到家。如果他们仍然坚持要您这样做,请像上面其他人一样记录下来。

#8 楼

我怎么能向我的客户解释这段代码有多糟糕?

也许您可以在房屋中使用类似管道的类比,随着时间的流逝,在修复和改建后,它们变得如此善变和耦合,以至于在修复时一件事,影响并可能破坏了某些其他东西,然后需要修复,而您根本无法知道所有发生这种情况的地方。真的给出了非技术客户会理解的简单而具体的示例吗?

您是对的,这是对上一位顾问在他们头脑中创造的视觉效果的反驳。我的建议是按照您的要求做,并给出简单而具体的示例。由于这是重新设计,因此说明如何在已编译的代码中定义的HTML片段与HTML页面的其余部分一起显示,以及更改如何影响或不影响页面的其余部分。也许相同的编译代码在应用一些“业务”规则后会呈现标记。显示差异。

这是一个非常棘手的常见问题。祝你好运。

#9 楼

诚实坦率。

但是最重要的是,不要从事无法满足您期望的工作。大多数人没有意识到承包商可以解雇客户,如果这项工作比它值得的多,他们可以也应该这样做。

#10 楼

这是我使用过的一个比喻(尽管我不保证它的有效性):想象他们的网站是一台物理机器,就像一台机械印刷机以某种方式接受输入。

他们可能会想到这台机器例如具有X组件和Y组件。实际上,它是20台左右相似的机器。他们中的一些人不再做任何事情,所有的人都尝试执行其他人已经执行的功能,除了前一位顾问以外,没有人见过像他们之前完全一样的东西。


“看到这个gizmo在这里解析post变量,然后将这个组件向下发送到if-elses的兔子洞中吗?不仅有一个
,每页中都有一个(或其他任何内容) ),其中有些
清除了输入内容,有些则没有(或全部没有),并且没有
读取了我所不知道的全部内容。“


评论


“想象一下他们的网站是一台物理机器,就像一台机械印刷机一样”-它在印钱!但是,因为它坏了,所以它并没有印刷出尽可能多的钱……应该吸引他们,-)

–莫格说要恢复莫妮卡
2015年4月21日在10:00

#11 楼

尚未真正提到的一点是,在这种情况下,您可能只是超越了客户真正想要的。过度成就感很棒,可以使您获得很多工作满意度。但是,如果客户根本不在乎,认为当前的性能“足够好”,并且只想进行一些小更新,则可能无法说服他们在您的代码上进行大笔投资来彻底检查代码库。

到那时,您可能需要决定是否坚持原则并拒绝从事会迫使您在尴尬的代码混乱中加上好名声的工作,或者是否可以hold之以鼻,进入,获取用胶带完成的工作,然后付款。

如果您确实决定继续使用胶带,请确保形成文件,文件并保持尽可能透明。您想要做的最后一件事是指责您将来会发生问题,这是由于您警告了客户某个应用程序缺陷而导致的,但是该客户认为当时不够重要。

就SQL注入风险而言,正如其他人所说的那样,您应该能够以显示风险的方式向他们证明这种风险,而无需在生产中进行任何实际的破坏性操作。但是,如果他们再次看到它,并且不愿意支付给您修复它,那么您在这种情况下就已经做好了诚信调查。

#12 楼

进入项目并建议重写第一件事,执行一些小的修改子集,并使用这些子集来说明它本来可以更简单,更便宜,这真是个菜鸟。那么,有一个明显的案例说明了为什么在字体成本较低的情况下,长期以来清洁剂开发成本的增加会导致较低的维护成本和更快的开发。

永远不要忘记,您从根本上要求他们付钱给您,以使自己的生活更轻松,他们认为,找到能够以Y成本获得X功能并放大项目复杂性的“家伙”,可能只是为您消除了机会。当您需要一个月的重写时间并且与原始开发人员会面时,才意识到这是一条艰难的路,只是要意识到整个应用程序是由开发人员在极其紧凑的窗口中编写的,他完全理解了所做出的所有折衷。如您所说,如果该应用程序内部看起来很恐怖,但外部功能很好,那么很可能是这种情况。通常,代码库中的技术债务是代码开发所依赖的资源限制的产物,并且如果他们不组建团队而是将事情外包出去……他们可能仍不认真对待维护。

我只是说'

#13 楼

我将在这里扮演魔鬼的拥护者(有点类似@khrome所说的话:“您没有付钱给客户以使您的生活更轻松”)。我什至会说您提出的案子过于单一,因为您以一般方式描述了该案。大多数新项目的新进顾问都会对前一个项目产生负面影响...我并不是说这就是您在这里所做的,但是在我们看到示例之前,我不能简单地相信您的话。

也就是说,我将尝试逐点解决您的问题:



SQL注入。好的,所以我想程序员使用的是字符串连接,而不是参数化的查询和/或存储过程。这很容易修复,尤其是在ADO.NET中...我个人会向客户端提及它,但不会在其中产生太大的作用。

HTML是在业务逻辑中生成的这将是一场噩梦。好吧,伙计,这是您给我提供更多细节的地方之一。除非您使用的是MVC,否则这种趋势很容易发生……但这不一定是一件坏事……这是大多数程序员会说“ goto不好;从不使用它”的东西之一,但是您知道吗?我在有意义的地方使用过goto!因此,您确定他们没有使用碰巧与业务代码DLL共享相同名称空间的帮助程序类吗?同样,隔离起来并不是那么困难。

业务逻辑遍及整个应用程序,有很多重复项,并且死胡同的代码什么也没做。客户只是要求您更改HTML / CSS。您为什么要完全关心这些问题?

它会不断抛出被窒息的异常,因此站点看起来运行平稳。再次,非常模糊。在任何应用程序中异常都是正常的,这就是为什么我们在代码中包含try / catch子句的原因。除非它们在UI中冒出气泡并破坏用户体验(例如不必要地显示HTTP 500),否则我也不认为这是您应该关心的事情。.

所以总之,我会建议您走高速公路。如果您认为这不值得花时间,并且想以牺牲客户为代价来重写它,那么就放弃工作吧。认真地说,最后,客户花了您的时间使整个事情以最少的$$$运转。

在我多年的实际经验中,我总是说我遇到的最好的程序员是那些可以通过编写最少代码而不是重写整个代码来使系统稳定的人。

编辑:我已经看到我的答案不是最受欢迎的一个(我已经预料到了),但我坚持我的回答。我对此进行了编辑,以使其不那么狡猾。 ;-)

#14 楼

当然,SQL注入攻击和应用程序中的其他功能缺陷优先,但您也可以“演示”不良的代码质量和做法。
使用代码度量工具,您可以清楚地演示代码有多糟糕,并向他展示了多少这将增加将来的任何更改和错误修复的成本。
我不熟悉.net环境,但是我敢肯定有几个可以借鉴的。

评论


为什么对此表示不满?当然,客户可能不是技术人员,但是代码指标会产生数字,每个人都可以理解。尤其是如果有据可查的文件,但不是太讲究技巧,请解释这些数字的含义

–莫格说要恢复莫妮卡
2015年4月21日在10:04