Skip to main content

Thảm họa PyYAML

PyYAML, thư viện parse YAML phổ biến bậc nhất của Python, được dùng trong các phần mềm dùng YAML như Ansible, SaltStack, ...

> YAML: YAML Ain't Markup Language™

Ví dụ Salt state:

install_network_packages:
  pkg.installed:
    - pkgs:
      - rsync
      - lftp
      - curl

Mặc định nguy hiểm

YAML không phải một ngôn ngữ/format đơn giản như JSON, nó có hàng tá tính năng mà có thể bạn không biết tới. Dùng YAML giống như dùng pickle hơn là json (có thể chứa object tùy ý).

def double(x):
    return x+x
import sys
yaml.dump(double, sys.stdout)
# !!python/name:__main__.double ''

Function mặc định (và siêu phổ biến) để đọc file YAML: yaml.load, có thể chạy code Python, và là tác giả của hàng loạt lỗ hổng bảo mật được gắn CVE:

  • CVE-2017-18342 In PyYAML before 5.1, the yaml.load() API could execute arbitrary code if used with untrusted data. The load() function has been deprecated in version 5.1 and the 'UnsafeLoader' has been introduced for backward compatibility with the function.
  • Rất nhiều nữa https://www.opencve.io/cve?vendor=pyyaml...

Đến sau 2017, người dùng mới bắt đầu làm quen với function mới yaml.safe_load, an toàn hơn.

Cài pip install 'pyyaml<5.1' để trải nghiệm CVE này:

python3 -c 'import yaml; yaml.load("!!python/object/new:os.system [echo EXPLOIT!]")'                              [0]
EXPLOIT!

Theo https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation

Phức tạp, nhiều phiên bản

JSON có... 1 phiên bản duy nhất?!!

YAML có 1.0 1.1 1.2 và còn nữa. Phiên bản 1.2 có từ 2009, mà PyYAML chỉ hỗ trợ YAML 1.1

>   - YAML 1.2:
    - Revision 1.2.2      # Oct 1, 2021 *New*
    - Revision 1.2.1      # Oct 1, 2009
    - Revision 1.2.0      # Jul 21, 2009
  - YAML 1.1

Muốn dùng YAML 1.2, phải dùng ruamel.yaml

  - PyYAML        # YAML 1.1, pure python and libyaml binding
  - ruamel.yaml   # YAML 1.2, update of PyYAML; comments round-trip

PyYAML 6.0+ không tương thích phiên bản cũ

Phiên bản mới nhất 6.0, ra đời năm 2021, không tương thích với code các bản cũ.

6.0

import yaml
yaml.load("key: value", Loader=yaml.CLoader)

CHỮ L ở Loader= VIẾT HOA

5

import yaml
yaml.load("key: value")

bản 6 bắt buộc argument Loader phải được set. Tới tháng 6 2023, tài liệu tutorial trang chủ vẫn không update https://pyyaml.org/wiki/PyYAMLDocumentation:

>>> yaml.load("""
... - Hesperiidae
... - Papilionidae
... - Apatelodidae
... - Epiplemidae
... """)

Issue GitHub: https://github.com/yaml/pyyaml/issues/576

May thay nếu dùng yaml.safe_load thì không đổi, nó sẽ gọi Loader=yaml.SafeLoader)

def safe_load(stream):
    """
    Parse the first YAML document in a stream
    and produce the corresponding Python object.

    Resolve only basic YAML tags. This is known
    to be safe for untrusted input.
    """
    return load(stream, SafeLoader)

Tham khảo

Kết luận

YAML không đơn giản như JSON, nếu không nhất thiết, chớ động vào.

Hết.

HVN at http://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺

Comments

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG