JezK
Edit File: incident_parser.cpython-311.opt-1.pyc
� "cɵ_�W}� � � d Z ddlZddlZddlZddlZddlZddlmZ ddlm Z ej e� � Z G d� d� � Z dS )z+Parser for WordPress plugin incident files.� N)�Path)� open_nofollowc � � e Zd ZdZededee dz fd�� � Zede de dededz fd�� � Zed e de dededz fd �� � Ze dedefd�� � ZdS ) �IncidentFileParsera' Parse incident files written by the WordPress plugin. These files have format: <?php __halt_compiler(); #{base64-encoded JSON data for incident} #{base64-encoded JSON data for incident} ... File pattern: wp-content/imunify-security/incidents/yyyy-mm-dd-hh.php � file_path�returnNc � � g } t t |� � � � 5 }t j t j |� � dd�� � 5 }t |d� � D ]G\ }}|� � � }| � |||� � }|�|� |� � �H ddd� � n# 1 swxY w Y ddd� � n# 1 swxY w Y n4# t $ r'}t � d||� � Y d}~dS d}~ww xY w|S )a� Parse an incident file, or None when it could not be read. A file that could not be read is not an empty one: the caller keeps it for the next cycle instead of discarding a batch it never saw. The file format is: - First line: <?php __halt_compiler(); - Following lines: #{base64-encoded JSON} Opens with O_NOFOLLOW to prevent reading arbitrary files if the incident file was replaced with a symlink. �r�utf-8)�encoding� Nz"Error reading incident file %s: %s)r �str�os�fdopen�dup� enumerate�strip� _process_line�append� Exception�logger�error) �clsr � incidents�fd�f�line_num�line�incident�es �^/opt/imunify360/venv/lib/python3.11/site-packages/defence360agent/wordpress/incident_parser.py� parse_filezIncidentFileParser.parse_file s� � � � � ��s�9�~�~�.�.� 7�"��Y�r�v�b�z�z�3��A�A�A� 7�Q�*3�A�q�/�/� 7� 7���$�#�z�z�|�|��#&�#4�#4�T�8�Y�#O�#O��#�/�%�,�,�X�6�6�6�� 7�7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7���� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7� 7���� 7� 7� 7� 7��� � � � ��L�L�4��� � � � �4�4�4�4�4����� ���� �s_ �C �*C� AB0�$C�0B4 �4C�7B4 �8C�;C �C�C �C�C � D�C?�?Dr r c �> � |sdS |� d� � r#t � d||j � � dS |� d� � s,t � d||j |dd� � � dS |dd� }| � |||� � S )aD Process a single line from an incident file. Args: line: The line content (already stripped) line_num: Line number for logging file_path: Path to the file being processed Returns: Parsed incident dictionary or None if line should be skipped Nz<?phpz!Skipping PHP header line %d in %s�#z&Line %d in %s doesn't start with #: %s�2 r )� startswithr �debug�name�_process_encoded_line)r r r r �encoded_datas r! r z IncidentFileParser._process_line? s� � � � ��4��?�?�7�#�#� ��L�L�3���� � � � �4� ���s�#�#� ��L�L�8�����S�b�S� � � � � �4� �A�B�B�x���(�(��x��K�K�K� r* c �( � t j |� � }|� d� � }t j |� � }t |t � � s,t � d||j |dd� � � dS | � |� � s7t � d||j |� d� � � � dS |S # t t j f$ r-}t � d||j |� � Y d}~dS d}~ww xY w)aM Decode base64-encoded JSON data from an incident line. Args: encoded_data: Base64-encoded JSON string line_num: Line number for logging file_path: Path to the file being processed Returns: Parsed incident dictionary or None if decoding/parsing fails r z&Line %d in %s is not a JSON object: %sN�d z"Line %d in %s has no usable ts: %r�tsz,Failed to decode base64 on line %d in %s: %s)�base64� b64decode�decode�json�loads� isinstance�dictr �warningr( �_has_valid_timestamp�getr �JSONDecodeErrorr )r r* r r � decoded_bytes�decoded_strr r s r! r) z(IncidentFileParser._process_encoded_linei s+ � � �"�,�\�:�:�M�'�.�.�w�7�7�K��z�+�.�.�H��h��-�-� ����<���N�����%� � � � �t��+�+�H�5�5� ����8���N��L�L��&�&� � � � �t��O���4�/�0� � � ��L�L�>����� � � � �4�4�4�4�4����� ���s% �A<C � A C �C �D�$"D�Dr c � � t | d � � }n# t t t f$ r Y dS w xY wt j |� � o|dk S )z�The timestamp decides the aggregation window, so it must be usable. json.loads accepts Infinity and NaN, which survive a bare > 0 check and blow up when the window is computed. r. Fr )�float�KeyError� TypeError� ValueError�math�isfinite)r r. s r! r7 z'IncidentFileParser._has_valid_timestamp� s\ � � ��x��~�&�&�B�B���)�Z�0� � � ��5�5� �����}�R� � �+�R�!�V�+s � �3�3)�__name__� __module__�__qualname__�__doc__�classmethodr �listr5 r"