[译] 防守式编程的计

  • 原文地址:The Art of Defensive
    Programming
  • 原文作者:Diego
    Mariani
  • 译文出自:掘金翻译计划
  • 译者:GiggleAll
  • 校对者:tanglie1993
    , fghpdf

为什么开发人员不修安全代码? 我们不再在这里讨论 “干净之代码
。我们由一个纯粹的角度,软件的安全性来讨论还多之东西。是的,因为一个不安全的软件几乎是尚未因此之。让咱来探视不安全的软件意味着什么。

  • 欧洲航天局之 Ariane 5 Flight 501 在起飞后 40
    秒(1996年6月4日)被破坏。10
    亿美元的
    原型火箭出于机载导航软件面临的不当而自毁。

  • 在 20 世纪 80 年代,一个治疗机中控制 Therac-25
    辐射的底代码错误,导致其给用过量的 X 射线致使至少五称患者身故。

  • MIM-104 爱国者的软件错误造成该系时钟在 100
    小时时内偏移三分之一秒,以至于无法稳定及拦截来袭导弹。伊拉克导弹袭击了沙特阿拉伯在达哈兰底一个军事大院(
    1991 年 2 月 25 日 ),杀害了 28 叫做美国丁。

这些事例可以被咱认识及编辑安全之软件,特别是在某些情况下是何等重要。在另外使用情况下,我们也应亮我们软件错误会带来吃咱们啊。

防守式编程角度一

缘何我觉得防守式编程在少数种类中是一个意识这些题材之好点子?

守卫不容许,因为无可能将可能发。

对于防御性编程有多定义,它还在安全性的级别跟公的软件类所用的资源级别。

防守式编程是一种防守式设计,旨在确保以奇怪之事态下软件的持续性功能,防守式编程实践时为用在高可用性,需要安全的地方

维基百科

我个人觉得这种艺术可当您处理一个老的、长期的、有为数不少人口与的档次。
例如,需要大量护卫的开源项目。

为了贯彻防守式编程方法,让自己谈谈自己个人简陋的眼光。

从没相信用户输入

假使你连会收取你意料之外的事物。这当是若当防守式程序员的主意,针对用户输入,或者平常上而的系统的各种东西。因为咱们得预想到意想不到的,尽量做到尽量严格。断言)你的输入值是你希望的。

航天科工 1

The best defense is a good offense

击就是最好好之防御

(将输入)列入白名单而不是将她坐黑名单中,例如,当证图像扩展名时,不反省无效的花色,而是检查中的色,排除有其他的种。
在 PHP 中,也发生过多底开源验证库来如你的办事还便于。

攻就是不过好的守卫,控制而从严。

采取数据抽象

OWASP
十生安全漏洞

中的第一只是流。这象征有人(很多丁)还尚无以安全工具来询问他们之数据库。请动数据库抽象包和仓库。在
PHP 中您得应用
PDO
来保基本的注入保护。

无须再过去轮子

君绝不框架(或微框架)?
你就算是爱慕无理由的做额外之办事。恭喜你!只要是通过完美测试、广受信赖的稳定性的代码,你就得尽管用于各种新特点(不仅是框架)的付出,而休是只有以它们是已前往好之车轮的因由而再度造轮子。你自己之轮子的绝无仅有原因是若得有免存或者存而切莫吻合您的要求(性能不优秀,缺少的功能等)。

良(使用框架)我们遂其为智能代码用,它值得拥有。

毫不相信开发人员

防守式编程可以同名防御性驾驶的物有关。在守卫驾驶被,我们只要我们周围的每个人犹生或发错误。
所以我们务必小心别人的行事。这些平适用于咱们的防守式编程,作为开发者,我们无应有相信任何开发者。我们呢如出一辙未应该相信我们的代码。

以广大口踏足的深类蒙,我们可以有无数不等的措施来编排和团队代码。
这吗恐怕致乱,甚至更多之失实。
这就是是干什么我们联合编码风格和利用代码检测器会如我们的生存更自在。

写SOLID代码

立是指向一个防守式程序员困难的地方,writing code that doesn’t
suck
。这是众人口懂得和座谈的工作,但尚无丁真正关注或投入是的注意力和奋力来贯彻
SOLID代码

深受咱们来拘禁一些糟糕的事例。

毫无:未初始化的习性

<?php

class BankAccount
{
    protected $currency = null;
    public function setCurrency($currency) { ... }
    public function payTo(Account $to,$amount)
    { 
        // sorry for this silly example
        $this->transaction->process($to,$amount,$this->currency);
    }
}

// I forgot to call $bankAccount->setCurrency('GBP');
$bankAccount->payTo($joe,100);

于这种情景下,我们必须记住,为了闹付款,我们用先调用 setCurrency

这是一个异常不好的事体,像这么的状态更改操作(发出付款)不应有在少单步骤使用简单只(或多只)公共措施。
我们照例可以出广大道来会,但是咱要就出一个简练的公措施,以改状态(对象应该永远不见面处于不一样的状态)。

当这种情景下,我们得开得重好,将非初始化的特性封装到 Money
对象中。

<?php

class BankAccount
{
    public function payTo(Account$to,Money$money){ ... }
}

$bankAccount->payTo($joe,newMoney(100,newCurrency('GBP')));

假设其万无一失。 毫无使不初始化的目标属性

Don’t: Leaking state outside class scope.

绝不:类作用域之外的展露状态。

<?php

class Message
{
    protected $content;
    public function setContent($content)
    {
        $this->content=$content;
    }
}

class Mailer
{
    protected $message;
    public function__construct(Message$message)
    {
        $this->message=$message;
    }
    public function sendMessage(
    {
        var_dump($this->message);
    }
}

$message = new Message();
$message->setContent("bob message");
$joeMailer = new Mailer($message);

$message->setContent("joe message");
$bobMailer = new Mailer($message);

$joeMailer->sendMessage();
$bobMailer->sendMessage();

以这种状况下,消息由此引用传递,结果用在个别栽情况下还是 “joe
message”
。 解决方案是当 Mailer 构造函数中克隆音对象。
但是咱们应有总是尝试使用一个(不可变的)值对象失去顶替一个简约的
Message mutable对象。当你可的上用不可变对象

<?php

class Message
{
    protected $content;
    public function __construct($content)
    {
        $this->content = $content;
    }
}

class Mailer 
{
    protected $message;
    public function __construct(Message $message)
    {
        $this->message = $message;
    }
    public function sendMessage()
    {
        var_dump($this->message);
    }
}

$joeMailer = new Mailer(new Message("bob message"));
$bobMailer = new Mailer(new Message("joe message"));

$joeMailer->sendMessage();
$bobMailer->sendMessage();

写测试

俺们还得说些什么?
写单元测试将扶持而遵守并的法,如强集,单一责任,低耦合和正确的靶子成
它不但拉而测试小单元,而且为能够测试你的目标的构造的方。
事实上,你会掌握地察看,为了测试你的略微作用要测试多少只单元以及你需要效法多少个目标,以贯彻100%的代码覆盖率。

总结

企您喜爱就首文章。
记住这些只是是建议,何时、何地采纳这些建议,这在你。

发表评论

电子邮件地址不会被公开。 必填项已用*标注