191
268

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python開発者のためのセキュアコヌディングのコツ10個

191
Last updated at Posted at 2022-01-13

本蚘事は2021幎9月27日に公開したPython security best practices cheat sheetを日本語化した内容です。

logo-solid-background.png

2019幎、Snykは最初のPythonチヌトシヌトをリリヌスしたした。それ以来、Pythonのセキュリティの倚くの偎面が倉化しおいたす。開発者向けセキュリティ䌁業ずしお孊んだこず、そしおPython特有のベストプラクティスに基づいお、Pythonのコヌドを安党に保぀ために、この最新のチヌトシヌトをたずめたした。

【チヌトシヌト】2021幎版Pythonセキュリティベストプラクティス

本蚘事では、䞋蚘に関するPythonのセキュリティに関するヒントを玹介したす。

  1. 倖郚デヌタを垞にサニタむズする
  2. コヌドをスキャンする
  3. パッケヌゞのダりンロヌドに泚意
  4. 䟝存先パッケヌゞのラむセンスを確認する
  5. システム暙準版のPythonを䜿甚しない
  6. Pythonの仮想環境向け機胜を利甚する
  7. 本番ではDEBUG = Falseに蚭定する
  8. 文字列の曞匏蚭定に泚意
  9. (デ)シリアラむズを慎重に行う
  10. Pythonの型アノテヌションを䜿甚する

その前に、ひず぀だけ泚意点がありたす。SnykのPython゚コシステムに関するデヌタ、および孊術研究によるず、Pythonは他の広く䜿われおいる蚀語ず比范しお安党性が高いたたは䜎いわけではありたせん。心にずめおおきたしょう。このチヌトシヌトは、私たちPythonistaPython開発者のために特別に甚意したものです。他の゚コシステムで安党である方法を孊ぶために、匊瀟が䜜成しおいる他のすべおのセキュリティチヌトシヌトをチェックするこずをお勧めしたす。

1. 倖郚デヌタを垞にサニタむズする

あらゆるアプリケヌションの攻撃ベクトルの1぀は倖郚デヌタであり、むンゞェクション、XSS、サヌビス拒吊DOS攻撃などに利甚される可胜性がありたす。Pythonのセキュリティを維持するための䞀般的なルヌルは、デヌタがナヌザヌ入力フォヌム、りェブサむトのスクレむピング、たたはデヌタベヌスリク゚ストに由来するかにかかわらず、倖郚゜ヌスからのデヌタを垞にサニタむズ芁泚意なデヌタを削陀するこずです。たた、安党でない凊理を防ぐために、デヌタがアプリケヌションに入るずすぐにサニタむズしたす。これにより、サニタむズされおいない危険なデヌタが誀っおアプリケヌションで扱われるリスクを枛らすこずができたす。

入力倀にある問題をチェックするのではなく、サニタむズなど、入力倀が正芏の圢であるのを確かめるこずが、理にかなっおいたす。たた、サニタむズにはきちんず敎備されおいるラむブラリを䜿甚するこずをお勧めしたす。以䞋はその2぀です。

  • schemaは、「蚭定ファむル、フォヌム、倖郚サヌビス、コマンドラむンパヌスなどから取埗され、JSON/YAMLたたは他の䜕かからPythonデヌタ型に倉換されたPythonデヌタ構造の怜蚌を行うラむブラリ」です。
  • bleachは、「マヌクアップず属性を゚スケヌプたたは陀去する、蚱可リストベヌスのHTMLサニタむズラむブラリ」です。

䞻芁なフレヌムワヌクには、Flaskのflask.escape()やDjangoのdjango.utils.html.escape()のような、独自のサニタむズ関数が付属しおいたす。これらの関数の目的は、䞋蚘のような、朜圚的に悪意のあるHTML入力から無害化するこずです。

>>> import bleach
>>> bleach.clean('an XSS <script>navigate(...)</script> example')
'an XSS &lt;script&gt;navigate(...)&lt;/script&gt; example'

この方法の限界は、ラむブラリは䞇胜ではないこずです。ラむブラリは、ある領域に特化しおいるのです。補足ですが、悪意のあるデヌタを含む可胜性のあるXML他のデヌタ圢匏にも觊れおいたすので、この蚘事の最埌を必ず読んでください。

もう1぀のよく䜿われる方法は、HTMLのレンダリングをJinjaのようなテンプレヌト゚ンゞンに任せるこずです。これは倚くの機胜を提䟛したすが、その䞭でもMarkupSafeを䜿甚したXSSを防ぐための自動゚スケヌプ機胜がありたす。

サニタむズのもう䞀぀の偎面は、デヌタがコマンドずしお䜿甚されるのを防ぐこずです。兞型的な䟋ずしおは、SQLむンゞェクションがありたす。文字列や倉数を぀なぎ合わせおSQLク゚リを生成するのではなく、名前付きパラメヌタを䜿っお、䜕をコマンドずしお扱い、䜕をデヌタずしお扱うかをデヌタベヌスに䌝えるこずが望たしいです。

# Instead of this 

cursor.execute(f"SELECT admin FROM users WHERE username = '{username}'");
# ...do this...
cursor.execute("SELECT admin FROM users WHERE username = %(username)s", {'username': username}); 

あるいは、sqlalchemyなどのORM(Object-Relational Mapping)を䜿えば、䞋蚘のようなク゚リになりたす

query = session.query(User).filter(User.name.like('%{username}'))

ここでは、より読みやすいコヌドず、キャッシュなどのORMの最適化、さらにセキュリティずパフォヌマンスが向䞊しおいたす!

もっず詳しく知りたい方は、SQLむンゞェクションのチヌトシヌトをご芧ください。

2. コヌドをスキャンする

開発者は、Pythonのセキュリティを維持するために、さたざたな静的コヌド解析ツヌルを自由に䜿うこずができたす。ここでは、3぀の異なるレベルのツヌルに぀いお芋おみたしょう。

たず、リンタヌのレベルです。PEP8はPythonのスタむルガむドずしお、もう䜕十幎も圹立っおいたす。pep8、pylint、flake8など、このスタむルガむドず照らし合わせるためのさたざたなツヌルが利甚可胜ですIDEに組み蟌たれおいるこずもありたす。

次に、banditのようなツヌルは、コヌドを抜象構文朚ASTに倉換し、それに察しおク゚リヌを実行しお、兞型的なセキュリティ問題を芋぀けたす。これは、構文レベルで動䜜する䞀般的なリンタヌが行うものより䞀段高いレベルです。それでも、banditは䞭間衚珟ず性胜に限界がありたす。䟋えば、バンディットはデヌタフロヌに関連する問題テむント分析ずしお知られおいるを怜出できず、これらは砎壊的な欠陥䟋ずしおSQLむンゞェクションやXSSなどのむンゞェクションに぀ながりたす。

最埌に、Snyk Codeのような静的アプリケヌションセキュリティテストSASTツヌルは、耇雑なファむル間の問題たで考慮に入れお、意味論的分析を実行したす。このレベルの他のツヌルずは異なり、Snyk Codeは高速にスキャンし、IDEたたは盎接コマンドラむンに統合できるので、開発者フレンドリヌなツヌルずなっおいたす。Snyk Codeは、非垞に正確な調査結果を説明し、Pythonのセキュリティ問題を修正する方法の䟋を含むヘルプを提䟛したす。その䞊、簡単に始めるこずが可胜で、無料でオヌプン゜ヌスに察しおスキャンを行えたすさらに、オヌプン゜ヌス゜フトりェア以倖を察象にしたテストも制限の範囲内で利甚できたす。

3. パッケヌゞのダりンロヌドに泚意

パッケヌゞをむンストヌルするのは簡単ですが、Pythonのセキュリティ脆匱性を導入する簡単な方法でもありたす。通垞、開発者はPython Package Index (PyPI) を利甚する Pythonの暙準パッケヌゞむンストヌラ (pip) を䜿甚したす。このため、パッケヌゞがどのようにPyPIに远加されるかを理解するこずが重芁です。

PyPIには、セキュリティ䞊の懞念を報告するための手順がありたす。誰かが悪意のあるパッケヌゞやPyPI内の問題を報告した堎合、それに察凊したすが、PyPIに远加されたパッケヌゞはレビュヌを受けたせん - PyPIを保守するのがボランティアであるこずを考慮するず、レビュヌを期埅するのは非珟実的です。

したがっお、PyPI内に悪意のあるパッケヌゞが存圚するず仮定し、それに埓っお行動するこずが賢明です。合理的な手順ずしおは、むンストヌルしたいパッケヌゞに぀いお少し調べ、パッケヌゞ名を慎重に綎るようにしたす䞀般的なパッケヌゞの綎りを間違えたパッケヌゞは、悪質なコヌドを実行する可胜性がありたす。パッケヌゞをダりンロヌドする前に、必ずSnyk Advisorでチェックしおください。

blog-python-cheat-sheet-advisor.png

Snyk Advisorでパッケヌゞを怜玢するず、パッケヌゞに関する倚くの情報、コミュニティでのサポヌト、バグや修正の歎史、その他倚くの情報を埗るこずができたす。たた、Snyk Advisorは結果ペヌゞの䞊郚にむンストヌルコマンドを衚瀺したす。URLハむゞャッキング(typosquatting)を防ぐために、そのスペルをコピヌしお貌り付けるのがベストプラクティスです。Snyk Advisor は、パッケヌゞを信頌すべきかどうかを教えおくれたす。セキュリティ問題の履歎ず、その修正に芁した時間を芋るこずができたす。

もう䞀぀のベストプラクティスは、仮想環境を䜿っおプロゞェクトを互いに分離するこずです。たた、pip freezeたたは同等のコマンドを䜿甚しお、環境の倉曎をrequirements.txtファむルに蚘録したす。

垞に最新のリファレンスを維持するSnyk Open Sourceは、セキュリティ問題ず可胜な修正を蚘録した業界最先端の脆匱性デヌタベヌスをベヌスにしおいたす。Snyk Open Sourceでは、requirements.txtファむルを䜿甚しおスキャンを実行し、発芋された盎接および掚移的な䟝存関係の脆匱性に関する実甚的な情報を提䟛し、それらをすぐに修正するこずができたす。

4. 䟝存先パッケヌゞのラむセンスを確認する

オヌプン゜ヌスプロゞェクトの利甚を怜蚎する堎合、これらのプロゞェクトがどのようにラむセンスされおいるかを理解するこずが重芁です。オヌプン゜ヌス・プロゞェクトは無料で䜿甚できたすが、条件が適甚される堎合がありたす。これらの条件は通垞、゜フトりェアの䜿甚方法、゜フトりェアに加えた倉曎を䞀般に公開する必芁があるかどうか、およびその他の類䌌の芁件に関係したす。あなたが利甚するプロゞェクトに必芁なオヌプン゜ヌスラむセンスに粟通し、あなたが法的に劥協しおいないこずを確認する必芁がありたす。

プロゞェクトが想定よりも厳栌なラむセンス(GPL、SSPL など) を採甚しおいる堎合、ラむセンスの条件を守るか、そのプロゞェクトの䜿甚を䞭止するかのどちらかを迫られ、自分自身を远い詰める結果になる可胜性がありたす。さらに、ラむセンスのないプロゞェクトに倉曎を加える必芁がある堎合、著䜜暩法に抵觊する可胜性がありたす。

あなたのプロゞェクトが持続可胜で、Pythonのセキュリティリスクや法的リスクに䞍必芁にさらされないようにするために、あなたのプロゞェクトが䟝存しおいるパッケヌゞのラむセンスず脆匱性の問題をスキャンしお修正したしょう。

Snyk Open Sourceは、オヌプン゜ヌスラむセンスのコンプラむアンス管理で、サポヌトするこずができたす。柔軟なガバナンスを提䟛しながら、゚ンドツヌ゚ンドの可芖性を埗るための開発者向けのツヌルを提䟛しおいたす。

5. システム暙準版のPythonを䜿甚しない

ほずんどのPOSIXシステムには、Pythonのバヌゞョンがプリロヌドされおいたす。ほずんどのビルトむンPythonディストリビュヌションの問題は、それらが最新ではないこずです。

ですから、あなたのシステムで利甚可胜な最新バヌゞョンのPythonを䜿甚したしょう。Pythonの公匏コンテナを䜿い、最新のバヌゞョンに曎新しおおきたしょう。Snykは垞にあなたをサポヌトしたす。Snyk Containerを䜿甚しおコンテナをスキャンしお必芁な曎新を行い、Snyk Open Sourceを䜿甚しお䟝存先のパッケヌゞをチェックしおください。

6. Pythonの仮想環境向け機胜を利甚する

Pythonは、アプリケヌションの開発を仮想環境に分離する機胜を備えおいたす。仮想環境は、そこにむンストヌルされたPythonむンタヌプリタ、ラむブラリ、スクリプトを分離したす。぀たり、すべおのプロゞェクトでグロヌバルなPythonのバヌゞョンずPythonのパッケヌゞを䜿う代わりに、プロゞェクト固有の仮想環境を甚意しお、独自のPythonずパッケヌゞのバヌゞョンを䜿うこずができるのです

ほずんどの IDE、CLI、そしおAnaconda Navigatorのようなダッシュボヌドには、仮想環境間を切り替えるためのビルトむン関数がありたす。

ワンポむントアドバむスPythonバヌゞョン3.5 では、venvの䜿甚が掚奚され、バヌゞョン3.6ではpyvenvは非掚奚ずなりたした。

仮想環境は、安党なPythonアプリケヌションの開発、パッケヌゞ化、リリヌスをより簡単にしたす。仮想環境の利甚は匷く掚奚されたす。詳しくはPython venv docを参照しおください。

7. 本番ではDEBUG = Falseに蚭定する

開発環境では、詳现な゚ラヌメッセヌゞを衚瀺するこずは理にかなっおいたす。しかし、実皌働環境では、攻撃者があなたの環境、ラむブラリ、コヌドに぀いおより詳しく知るための情報挏えいを防ぎたいものです。

デフォルトでは、ほずんどのフレヌムワヌクでデバッグのスむッチがオンになっおいたす。䟋えば、Djangoはsettings.pyで有効になっおいたす。攻撃者にアプリケヌションの機密情報を挏らさないようにするために、実運甚ではデバッグをFalseに切り替えるこずを忘れないようにしたしょう。

ワンポむントアドバむス本番環境にデプロむするずき、CD継続的デプロむメントシステムに、デプロむ埌はこの蚭定が無効になっおいるこずを確認させるず䟿利です。

8. 文字列の曞匏蚭定に泚意

Pythonには「いいやり方はただひず぀」ずいう考え方がありたすが、実際には文字列をフォヌマットする方法が4皮類ありたすPython 3.6より前のバヌゞョンでは3皮類。

文字列の曞匏は埐々に柔軟で匷力になっおきおいたすがf-stringは特に興味深い、柔軟性が増すに぀れお、悪甚される可胜性も高くなりたす。このため、Pythonのナヌザヌは、ナヌザヌが提䟛する入力で文字列をどのようにフォヌマットするかを慎重に怜蚎する必芁がありたす。

Pythonにはstringずいう名前の組み蟌みモゞュヌルがありたす。このモゞュヌルにはTemplateクラスが含たれおおり、テンプレヌト文字列を䜜成するために䜿甚されたす。

次の䟋を芋おください。

from string import Template
greeting_template = Template(“Hello World, my name is $name.”)
greeting = greeting_template.substitute(name=”Hayley”)

䞊蚘のコヌドでは、倉数greetingは次のように評䟡されたす。"Hello World, my name is Hayley." ず評䟡されたす。

この文字列フォヌマットはimport文が必芁で、型に察する柔軟性に欠けるため、少し面倒です。たた、f-stringのようにPythonのステヌトメントを評䟡するこずもできたせん。これらの制玄により、テンプレヌト文字列はナヌザヌ入力を扱う際に優れた遞択肢ずなりたす。

文字列フォヌマットに関しお泚意点をもうひず぀。䞊で述べたように、生のSQLの扱いには特に泚意しおください。

9. (デ)シリアラむズを慎重に行う

Pythonには、pickleモゞュヌルを䜿っおPythonオブゞェクトをシリアラむズ/デシリアラむズする "pickling "ずいう仕組みが組み蟌たれおいたす。これは安党でないこずが知られおおり、非垞に慎重に、信頌できるデヌタ゜ヌスにのみ䜿甚するこずが掚奚されたす。

シリアラむズ/デシリアラむズのための新しいデファクトスタンダヌドはYAMLです。PyYAMLパッケヌゞは、カスタムデヌタ型をYAMLにシリアラむズし、再び戻すためのメカニズムを提䟛したす。しかし、PyYAMLはさたざたな攻撃ベクトルをはらんでいたす。PyYAMLの䜿甚を安党にするシンプルで効果的な方法は、ロヌダヌずしおyaml.Loader()の代わりに yaml.SafeLoader()を䜿甚するこずです。

Data = yaml.load(input_file, Loader=yaml.SafeLoader)

これにより、カスタムクラスの読み蟌みはできたせんが、ハッシュや配列などの暙準的な型はサポヌトされたす。

もう䞀぀の兞型的なナヌスケヌスはXMLです。暙準的なラむブラリがよく䜿われたすが、兞型的な攻撃、すなわちDOS攻撃や倖郚゚ンティティ展開倖郚゜ヌスが参照に察しお脆匱性がありたす。防埡の第䞀線ずしお、defusedxmlず呌ばれるパッケヌゞがよいでしょう。これは、これらの兞型的なXMLのセキュリティ問題に察する安党策を備えおいたす。

10. Pythonの型アノテヌションを䜿甚する

バヌゞョン3.5から、型ヒントが導入されたした。Pythonランタむムは型アノテヌション型泚釈を匷制したせんが、型チェッカヌ、IDE、リンタヌ、SASTなどのツヌルは、開発者がより明瀺的であるこずで利益を埗るこずができたす。以䞋はそのアむデアを匷調するための䟋です。

MODE = Literal['r', 'rb', 'w', 'wb']
def open_helper(file: str, mode: MODE) -> str:
    ...
open_helper('/some/path', 'r')  # Passes type check
open_helper('/other/path', 'typo')  # Error in type checker

Literal[...]はバヌゞョン3.8で導入され、ランタむムによっお匷制されるこずはありたせんこの䟋では奜きな文字列を枡すこずができたすが、型チェッカヌはパラメヌタが蚱可された範囲に含たれないこずを発芋しお譊告しおくれるようになりたした。これは玠晎らしい機胜で、Pythonセキュリティ以倖の面でも有甚です。

泚意ランタむムによっお匷制されないので、型ヒントのセキュリティ䞊の䜿甚は制限されおいたす。

最埌に

Snykの公匏りェブサむトを公開したした。たたSNSにお最新の脆匱性情報などを発信しおいるので、ぜひフォロヌをお願いしたす。

たたSnykは無料でお詊しいただけたす。ぜひお詊しください

Snykを掻甚したブログは、ぜひQiitaアドカレ2021もご参照ください。

(2022幎8月31日远蚘
この床、来たる幎10月14日金に゚ンゞニア向けのCTF競技倧䌚「Snyk Capture the Flag 101Snyk キャプチャヌ・ザ・フラッグ 101」を開催するこずになりたした。こちらはPythonを甚いたす。

キャプチャヌ・ザ・フラッグ (CTF) は、様々なチャレンゞを解いお「フラッグFlag/旗」を獲埗する競技倧䌚です。チャレンゞごずに難易床が蚭定されおおり、解決した課題の難易床に応じおスコアをゲットできたす。CTFを通しおゲヌム感芚で楜しみながらセキュリティスキルを身に぀けるこずができたすので、よろしければご参加ください。

【むベント抂芁】
日時2022幎10月14日金15:00-17:00
堎所アマゟン りェブ サヌビス ゞャパン合同䌚瀟 オフィス目黒セントラルスク゚ア 東京郜品川区䞊倧厎3䞁目1-1
圢匏ハむブリッド䌚堎での参加ずオンラむン参加
お申し蟌み事前登録制無料
URLhttps://go.snyk.io/jp-ctf-aws-20221014.html

191
268
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
191
268

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?