不適切なコーディングパターンは、セキュリティ上の大きな問題につながる可能性があります...では、なぜ私たちはそれを奨励するのでしょうか?

2022年11月03日掲載
マティアス・マドゥ博士著
ケーススタディ

不適切なコーディングパターンは、セキュリティ上の大きな問題につながる可能性があります...では、なぜ私たちはそれを奨励するのでしょうか?

2022年11月03日掲載
マティアス・マドゥ博士著
リソースを見る
リソースを見る

この記事のバージョンは、以下のサイトに掲載されています。 DZone.この記事は更新され、ここにシンジケートされています。

この時点で永遠とも思えるほど、私たちは、ソフトウェア開発の最初からセキュリティのベストプラクティスを考慮する、SDLCにおける「左遷」について議論してきました。DevSecOpsは、セキュリティに対する責任の共有と、セキュリティを意識した開発者がコードを書きながら一般的な脆弱性を阻止する力を強調したため、少なからず大きな飛躍を遂げました。 

また、開発者の参加とスキルアップのために選択するセキュアコードトレーニングの種類によって、大きな違いが生じることも、やはり何年も前からわかっています。規制遵守だけを動機とする労力の少ないソリューションでは、将来の優秀なセキュリティ人材を育成することはできませんし、ほとんどのセキュリティ意識の専門家はそのことに気付いています。動的で文脈に応じた学習が最適ですが、そのニュアンスを理解することが非常に重要です。 

脅威と戦うチャンスを得ようとするならば(脅威は常に組織に対して優位に立つ)、開発者には、ベストプラクティスに基づいたスキルを継続的に構築する階層的な学習による、総合的なトレーニング環境が必要なのです。

開発者主導の防御的なセキュリティ対策は、自動的には勝てない。

私たちの理念は、予防的なセキュリティ戦略の中心をなすのは開発者であり、コードレベル以上であることを中心に展開されています。これは当然のことで、セキュリティに精通した開発者は、お粗末なコーディングパターンに見られる一般的なセキュリティバグを阻止する最も簡単な方法を提供します(最近の破壊的な例としてLog4Shell のようなもの)。

しかし、開発者のスキルアップのために取り組むことのできる防御技術は、たとえ同じトレーニングバケットに正しく存在するとしても、さまざまです。 

例えば、ケーキを焼くときに、「こうしてはいけない」という指示だけで焼くとしたらどうでしょう。焼きすぎるな」「卵を忘れるな」では、解釈の余地があり、失敗の可能性が高く、最終的には「Nailed It! 失敗した!.同じことが、防御的なセキュリティ教育にも当てはまります。「してはいけないこと」は、会話のごく限られた部分であり、防御的な考え方で本当に行動するための実践的なアドバイスを提供するものではありません。

開発者は、脆弱性がどのように機能するか、なぜ危険か、どのようなパターンが脆弱性を引き起こすか、どのような設計やコーディングパターンが脆弱性を修正するかについて、彼らの世界で意味のある文脈で基礎的な理解がなければ、脆弱性削減にプラスの影響を与えることはありません。足場となるアプローチは、安全なコーディング、コードベースの防御、および、セキュリティを意識した開発者としての立場の意味を全体的に把握するために、知識の層を重ねることを可能にします。これは、脅威のモデル化と防御戦略において非常に重要な、水平思考スキルを磨くために重要です。 

コーディングの悪いパターンを強化してしまうことは、無視できない落とし穴です。

開発者の学習方法の中には、技術的にはコードの安全性を検証していても、「守り」の部分、つまり攻めの技術で構成されたトレーニングでは、悪い習慣を強化してしまうという残念な現実があります。 

高品質なコードを作成することは、すべてのソフトウェア開発における基本であるべきですが、「品質」の定義にはまだ議論があるようです。現実には、安全でないコードは、たとえそれが機能的で美しくても、高品質のコードと見なすことはできません。また、セキュア なコードが本質的に高品質であるわけでもないというのがキッカケです。言い換えれば、不適切なコーディングパターンは、セキュリティの問題を修正することができますが、その際に別の問題を引き起こしたり、ソフトウェアを完全に破壊してしまう可能性があります。 

壊れた認証の修正という形で質の悪いコードの例と、ベストプラクティスのための最も安全なバージョンを見てみましょう。

を使用しています。
System.Collections.Genericを使用しています。
System.Linqを使用しています。
System.Threading.Tasksを使用しています。
Microsoft.AspNetCore.Authorizationを使用しています。
Microsoft.AspNetCore.Http.Libraryを使用しています。
Microsoft.AspNetCore.Mvcを使用しています。
namespace BadFixesAPI.Controllers
{
    [Route("api/[controller]")]を使用します。
    [ApiController】です。]
    public class AlertsController : ControllerBase.
    {
        private DatabaseContext context = new DatabaseContext();
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Does not ensure that the user is authenticated 
        public IEnumerable<Alert> Get()
        {
            context.GetAlerts()を返します。
        }
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Ensures that the user is authenticated, but does not check any roles
        [Authorize()]を使用します。
        public IEnumerable<Alert> GetBadFix()
        {
            context.GetAlerts()を返します。
        }
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Ensures that the user is authenticated, AND that they have the "Administrator" role
        [Authorize(Roles = "Administrator")]。
        public IEnumerable<Alert> GetGoodFix()
        {
            context.GetAlerts()を返します。
        }
    }
}

最初の例では、ユーザが認証されているかどうかを確認するチェックがありません。2番目は、認証チェックを行う点では優れていますが、割り当てられたロールと、要求された情報に対して十分な権限があるかどうかを調査することに失敗しています。3つ目は、ユーザーの認証と、そのユーザーが「Administrator」ロールを割り当てられているかどうかの両方をチェックします。最小権限のアクセス制御がほとんどの場合において標準であるべき時代において、情報を知る必要がある場合にのみアクセスできるように役割を設定し、確認することは非常に重要です。 

開発者にとっての最優先事項は機能を構築することであり、セキュリティが意図的に後回しにされているわけではありませんが、セキュリティバグにつながるお粗末なコーディングパターンを回避するスキルを必ずしも持っていませんし、優れたエンジニアのベンチマークにセキュリティコーディングの腕前が含まれることはほとんどありません。私たちは、機能が十分に素晴らしいものであれば、そのような悪い習慣を間接的に奨励しており、この考え方こそ変えなければなりません。問題は、いくつかの学習経路が実践的なコード修正を推奨しているため、安全ではあるが標準以下の品質のコードが強化される可能性があることです。これは安全だ/これは安全ではない」という二元的な判断でassessment 、バグを解決しソフトウェアの完全性を維持するために本当に最善の方法かどうかを深く検討しないため、細部にまで気がつかない悪魔が潜んでいるのです。 

セキュアコーディングの全プロセスを開発者に見せることなく、このアプローチは、解決しようとする同じ問題を永続させることになります。赤信号を無視して、生け垣の間を通り抜け、横断歩道を渡る歩行者をぎりぎりで見落としても、合格となります。赤信号を無視して、生け垣をすり抜け、横断歩道を渡る歩行者をギリギリで見落として、目的地に到着したのです。目標は達成しましたが、そこに至るまでの道のりが最も重要です。 

開発者は、安全なソフトウェアを作ることにもっと関心を持つようになる必要があります。

現代の開発者は多くの業務をこなさなければならないため、セキュリティトレーニングを退屈に感じるのは当然です。特に、平日の業務を考慮して実施されておらず、締切や優先事項から遠ざかっている場合はそうです。また、定期的で適切な学習機会や補助的なツールで培ったスキルがないのに、セキュアコーディングに重点を置くようにKPIを変更するのは完全に不当です。しかし、セキュアなソフトウェア開発の重要性はいくら強調してもし過ぎることはありませんし、開発者をセキュアコーディングの側に置くことは非常に重要です。 

元開発者である私たちは、一般に、優れた仕事をしたいと思う ものであり、アウトプットの品質という点で他の人より優れていると見なされることは、非常にモチベーションの高いことです。開発者に継続的なセキュリティスキル向上のインセンティブを与えることは当然のことであり、コードレベルのセキュリティの重要性を認識した開発者には報酬を与えるべきである。セキュリティチャンピオンプログラム、バグ報奨金、ハッカソンなどは、積極的なセキュリティ文化を構築する絶好の機会であり、腕まくりして参加した者は戦利品を手に入れるべきである。

リソースを見る
リソースを見る

著者

マティアス・マドゥ博士

マティアスは、15年以上のソフトウェアセキュリティの実務経験を持つ研究者・開発者です。フォーティファイ・ソフトウェア社や自身の会社(Sensei Security)などでソリューションを開発してきました。キャリアの中で、Matiasは、商用製品につながる複数のアプリケーションセキュリティ研究プロジェクトを主導し、10件以上の特許を取得しています。また、RSAカンファレンス、Black Hat、DefCon、BSIMM、OWASP AppSec、BruConなどの世界的なカンファレンスで定期的に講演を行っているほか、高度なアプリケーションセキュリティトレーニング(courses )の講師も務めています。

Matiasはゲント大学でコンピュータ工学の博士号を取得し、アプリケーションの内部構造を隠すためのプログラム難読化によるアプリケーションセキュリティを研究しました。

もっと知りたい?

セキュアコーディングに関する最新の知見をブログでご紹介しています。

当社の豊富なリソースライブラリは、安全なコーディングアップスキルに対する人間的なアプローチを強化することを目的としています。

ブログを見る
もっと知りたい?

開発者主導のセキュリティに関する最新の研究成果を入手する

ホワイトペーパーからウェビナーまで、開発者主導のセキュアコーディングを始めるために役立つリソースが満載のリソースライブラリです。今すぐご覧ください。

リソース・ハブ

不適切なコーディングパターンは、セキュリティ上の大きな問題につながる可能性があります...では、なぜ私たちはそれを奨励するのでしょうか?

2022年11月03日掲載
マティアス・マドゥ博士著

この記事のバージョンは、以下のサイトに掲載されています。 DZone.この記事は更新され、ここにシンジケートされています。

この時点で永遠とも思えるほど、私たちは、ソフトウェア開発の最初からセキュリティのベストプラクティスを考慮する、SDLCにおける「左遷」について議論してきました。DevSecOpsは、セキュリティに対する責任の共有と、セキュリティを意識した開発者がコードを書きながら一般的な脆弱性を阻止する力を強調したため、少なからず大きな飛躍を遂げました。 

また、開発者の参加とスキルアップのために選択するセキュアコードトレーニングの種類によって、大きな違いが生じることも、やはり何年も前からわかっています。規制遵守だけを動機とする労力の少ないソリューションでは、将来の優秀なセキュリティ人材を育成することはできませんし、ほとんどのセキュリティ意識の専門家はそのことに気付いています。動的で文脈に応じた学習が最適ですが、そのニュアンスを理解することが非常に重要です。 

脅威と戦うチャンスを得ようとするならば(脅威は常に組織に対して優位に立つ)、開発者には、ベストプラクティスに基づいたスキルを継続的に構築する階層的な学習による、総合的なトレーニング環境が必要なのです。

開発者主導の防御的なセキュリティ対策は、自動的には勝てない。

私たちの理念は、予防的なセキュリティ戦略の中心をなすのは開発者であり、コードレベル以上であることを中心に展開されています。これは当然のことで、セキュリティに精通した開発者は、お粗末なコーディングパターンに見られる一般的なセキュリティバグを阻止する最も簡単な方法を提供します(最近の破壊的な例としてLog4Shell のようなもの)。

しかし、開発者のスキルアップのために取り組むことのできる防御技術は、たとえ同じトレーニングバケットに正しく存在するとしても、さまざまです。 

例えば、ケーキを焼くときに、「こうしてはいけない」という指示だけで焼くとしたらどうでしょう。焼きすぎるな」「卵を忘れるな」では、解釈の余地があり、失敗の可能性が高く、最終的には「Nailed It! 失敗した!.同じことが、防御的なセキュリティ教育にも当てはまります。「してはいけないこと」は、会話のごく限られた部分であり、防御的な考え方で本当に行動するための実践的なアドバイスを提供するものではありません。

開発者は、脆弱性がどのように機能するか、なぜ危険か、どのようなパターンが脆弱性を引き起こすか、どのような設計やコーディングパターンが脆弱性を修正するかについて、彼らの世界で意味のある文脈で基礎的な理解がなければ、脆弱性削減にプラスの影響を与えることはありません。足場となるアプローチは、安全なコーディング、コードベースの防御、および、セキュリティを意識した開発者としての立場の意味を全体的に把握するために、知識の層を重ねることを可能にします。これは、脅威のモデル化と防御戦略において非常に重要な、水平思考スキルを磨くために重要です。 

コーディングの悪いパターンを強化してしまうことは、無視できない落とし穴です。

開発者の学習方法の中には、技術的にはコードの安全性を検証していても、「守り」の部分、つまり攻めの技術で構成されたトレーニングでは、悪い習慣を強化してしまうという残念な現実があります。 

高品質なコードを作成することは、すべてのソフトウェア開発における基本であるべきですが、「品質」の定義にはまだ議論があるようです。現実には、安全でないコードは、たとえそれが機能的で美しくても、高品質のコードと見なすことはできません。また、セキュア なコードが本質的に高品質であるわけでもないというのがキッカケです。言い換えれば、不適切なコーディングパターンは、セキュリティの問題を修正することができますが、その際に別の問題を引き起こしたり、ソフトウェアを完全に破壊してしまう可能性があります。 

壊れた認証の修正という形で質の悪いコードの例と、ベストプラクティスのための最も安全なバージョンを見てみましょう。

を使用しています。
System.Collections.Genericを使用しています。
System.Linqを使用しています。
System.Threading.Tasksを使用しています。
Microsoft.AspNetCore.Authorizationを使用しています。
Microsoft.AspNetCore.Http.Libraryを使用しています。
Microsoft.AspNetCore.Mvcを使用しています。
namespace BadFixesAPI.Controllers
{
    [Route("api/[controller]")]を使用します。
    [ApiController】です。]
    public class AlertsController : ControllerBase.
    {
        private DatabaseContext context = new DatabaseContext();
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Does not ensure that the user is authenticated 
        public IEnumerable<Alert> Get()
        {
            context.GetAlerts()を返します。
        }
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Ensures that the user is authenticated, but does not check any roles
        [Authorize()]を使用します。
        public IEnumerable<Alert> GetBadFix()
        {
            context.GetAlerts()を返します。
        }
        [HttpGet(Name = "GetAlerts")】を参照してください。]
        // Ensures that the user is authenticated, AND that they have the "Administrator" role
        [Authorize(Roles = "Administrator")]。
        public IEnumerable<Alert> GetGoodFix()
        {
            context.GetAlerts()を返します。
        }
    }
}

最初の例では、ユーザが認証されているかどうかを確認するチェックがありません。2番目は、認証チェックを行う点では優れていますが、割り当てられたロールと、要求された情報に対して十分な権限があるかどうかを調査することに失敗しています。3つ目は、ユーザーの認証と、そのユーザーが「Administrator」ロールを割り当てられているかどうかの両方をチェックします。最小権限のアクセス制御がほとんどの場合において標準であるべき時代において、情報を知る必要がある場合にのみアクセスできるように役割を設定し、確認することは非常に重要です。 

開発者にとっての最優先事項は機能を構築することであり、セキュリティが意図的に後回しにされているわけではありませんが、セキュリティバグにつながるお粗末なコーディングパターンを回避するスキルを必ずしも持っていませんし、優れたエンジニアのベンチマークにセキュリティコーディングの腕前が含まれることはほとんどありません。私たちは、機能が十分に素晴らしいものであれば、そのような悪い習慣を間接的に奨励しており、この考え方こそ変えなければなりません。問題は、いくつかの学習経路が実践的なコード修正を推奨しているため、安全ではあるが標準以下の品質のコードが強化される可能性があることです。これは安全だ/これは安全ではない」という二元的な判断でassessment 、バグを解決しソフトウェアの完全性を維持するために本当に最善の方法かどうかを深く検討しないため、細部にまで気がつかない悪魔が潜んでいるのです。 

セキュアコーディングの全プロセスを開発者に見せることなく、このアプローチは、解決しようとする同じ問題を永続させることになります。赤信号を無視して、生け垣の間を通り抜け、横断歩道を渡る歩行者をぎりぎりで見落としても、合格となります。赤信号を無視して、生け垣をすり抜け、横断歩道を渡る歩行者をギリギリで見落として、目的地に到着したのです。目標は達成しましたが、そこに至るまでの道のりが最も重要です。 

開発者は、安全なソフトウェアを作ることにもっと関心を持つようになる必要があります。

現代の開発者は多くの業務をこなさなければならないため、セキュリティトレーニングを退屈に感じるのは当然です。特に、平日の業務を考慮して実施されておらず、締切や優先事項から遠ざかっている場合はそうです。また、定期的で適切な学習機会や補助的なツールで培ったスキルがないのに、セキュアコーディングに重点を置くようにKPIを変更するのは完全に不当です。しかし、セキュアなソフトウェア開発の重要性はいくら強調してもし過ぎることはありませんし、開発者をセキュアコーディングの側に置くことは非常に重要です。 

元開発者である私たちは、一般に、優れた仕事をしたいと思う ものであり、アウトプットの品質という点で他の人より優れていると見なされることは、非常にモチベーションの高いことです。開発者に継続的なセキュリティスキル向上のインセンティブを与えることは当然のことであり、コードレベルのセキュリティの重要性を認識した開発者には報酬を与えるべきである。セキュリティチャンピオンプログラム、バグ報奨金、ハッカソンなどは、積極的なセキュリティ文化を構築する絶好の機会であり、腕まくりして参加した者は戦利品を手に入れるべきである。

弊社製品や関連するセキュアコーディングのトピックに関する情報をお送りする許可をお願いします。当社は、お客様の個人情報を細心の注意を払って取り扱い、マーケティング目的で他社に販売することは決してありません。

送信
フォームを送信するには、「Analytics」のCookieを有効にしてください。完了したら、再度無効にしてください。