Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Padding #37340

Merged
merged 26 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Packs/ApiModules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ This pack is intended for common API logic across integrations. It is not a part

To use an API module, use `import *` in the integration script, under the `main` function.
The import line will be replaced by the common logic code and can be used in the integration in the linting process.
This prevents working with the `Export to Demisto` capability in the PyCharm plugin.
10 changes: 10 additions & 0 deletions Packs/ApiModules/ReleaseNotes/2_2_30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#### Scripts

##### MicrosoftGraphMailApiModule

Fixed an issue where the following commands failed to decode Base64-encoded attachments or images inside the html body when provided without padding:
- ***send-mail***
- ***reply-mail***
- ***msgraph-mail-get-attachment***
- ***fetch-incidents***
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,13 @@ def _get_email_attachments(self, message_id, user_id=None, overwrite_rate_limit_
if not attachment_name.isascii():
try:
demisto.debug(f"Trying to decode the attachment file name: {attachment_name}")
attachment_name = base64.b64decode(attachment_name) # type: ignore
attachment_name = b64_decode(attachment_name) # type: ignore
except Exception as e:
demisto.debug(f"Could not decode the {attachment_name=}: error: {e}")

if attachment_type == self.FILE_ATTACHMENT:
try:
attachment_content = base64.b64decode(attachment.get('contentBytes', ''))
attachment_content = b64_decode(attachment.get('contentBytes', ''))
except Exception as e: # skip the uploading file step
demisto.info(f"failed in decoding base64 file attachment with error {str(e)}")
continue
Expand Down Expand Up @@ -1163,7 +1163,7 @@ def handle_html(htmlBody):
att = {
'maintype': maintype,
'subtype': subtype,
'data': base64.b64decode(m.group(3)),
'data': b64_decode(m.group(3)),
'name': name,
'cid': f'{name}@{str(uuid.uuid4())[:8]}_{str(uuid.uuid4())[:8]}',
}
Expand Down Expand Up @@ -1345,7 +1345,7 @@ def file_result_creator(raw_attachment: dict, legacy_name=False) -> dict:
name = f"{content_id}-attachmentName-{name}"
data = raw_attachment.get('contentBytes')
try:
data = base64.b64decode(data) # type: ignore
data = b64_decode(data) # type: ignore
return fileResult(name, data)
except binascii.Error:
raise DemistoException('Attachment could not be decoded')
Expand Down
2 changes: 1 addition & 1 deletion Packs/ApiModules/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ApiModules",
"description": "API Modules",
"support": "xsoar",
"currentVersion": "2.2.29",
"currentVersion": "2.2.30",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/Base/ReleaseNotes/1_35_6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Scripts

##### CommonServerPython

Added support for decoding to binary base 64 provided strings with no padding, to avoid "Incorrect padding" error.
20 changes: 18 additions & 2 deletions Packs/Base/Scripts/CommonServerPython/CommonServerPython.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from __future__ import print_function

import base64
import binascii
import gc
import json
import logging
Expand Down Expand Up @@ -39,9 +40,9 @@ def __line__():
return cf.f_back.f_lineno # type: ignore[union-attr]


# 43 - The line offset from the beginning of the file.
# The number is the line offset from the beginning of the file. If you added an import, update this number accordingly.
_MODULES_LINE_MAPPING = {
'CommonServerPython': {'start': __line__() - 44, 'end': float('inf')},
'CommonServerPython': {'start': __line__() - 45, 'end': float('inf')},
}

XSIAM_EVENT_CHUNK_SIZE = 2 ** 20 # 1 Mib
Expand Down Expand Up @@ -1409,6 +1410,21 @@ def b64_encode(text):
return res


def b64_decode(b64_str):
"""
Decode a str in a base 64 format to a picture.
Replaces the use of base64.b64decode function which doesn't add padding to the supplied str.

:param b64_str: string to decode
:type b64_str: str
:return: decoded binary
:rtype: bytes
"""
b64 = b64_str.encode('ascii')
b64 += b'=' * (-len(b64) % 4) # add padding
return binascii.a2b_base64(b64)


def encode_string_results(text):
"""
Encode string as utf-8, if any unicode character exists.
Expand Down
22 changes: 21 additions & 1 deletion Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
DBotScoreType, DBotScoreReliability, Common, send_events_to_xsiam, ExecutionMetrics,
response_to_context, is_integration_command_execution, is_xsiam_or_xsoar_saas, is_xsoar,
is_xsoar_on_prem, is_xsoar_hosted, is_xsoar_saas, is_xsiam, send_data_to_xsiam,
censor_request_logs, censor_request_logs, safe_sleep, get_server_config
censor_request_logs, censor_request_logs, safe_sleep, get_server_config, b64_decode
)

EVENTS_LOG_ERROR = \
Expand Down Expand Up @@ -3821,6 +3821,26 @@ def test_b64_encode(_input, expected_output):
assert output == expected_output, 'b64_encode({}) returns: {} instead: {}'.format(_input, output, expected_output)


B64_STR = 'This is a test!'
DECODED_B64 = b'N\x18\xac\x8a\xc6\xadz\xcb'
CASE_NO_PADDING = (B64_STR, DECODED_B64)
CASE_LESS_PADDING = (B64_STR + '=', DECODED_B64)
CASE_WITH_PADDING = (B64_STR + '==', DECODED_B64)
CASE_TOO_MUCH_PADDING = (B64_STR + '===', DECODED_B64)


@pytest.mark.parametrize('str_to_decode, expected_encoded',
(CASE_NO_PADDING, CASE_WITH_PADDING, CASE_LESS_PADDING, CASE_TOO_MUCH_PADDING))
def test_b64_decode(str_to_decode, expected_encoded):
"""
Given: A base 64 encoded str that represents an image, with different paddings.
When: Decoding it to an image file.
Then: The str is decoded to binary.
"""
encoded = b64_decode(str_to_decode)
assert encoded == expected_encoded


def test_traceback_in_return_error_debug_mode_on(mocker):
mocker.patch.object(demisto, 'command', return_value="test-command")
mocker.spy(demisto, 'results')
Expand Down
2 changes: 1 addition & 1 deletion Packs/Base/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Base",
"description": "The base pack for Cortex XSOAR.",
"support": "xsoar",
"currentVersion": "1.35.5",
"currentVersion": "1.35.6",
"author": "Cortex XSOAR",
"serverMinVersion": "6.0.0",
"url": "https://www.paloaltonetworks.com/cortex",
Expand Down
2 changes: 1 addition & 1 deletion Packs/Gmail/Integrations/Gmail/Gmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -1939,7 +1939,7 @@ def handle_html(htmlBody):
attachment = {
'maintype': maintype,
'subtype': subtype,
'data': base64.b64decode(m.group(3)),
'data': b64_decode(m.group(3)),
'name': name,
'cid': cid,
'ID': cid
Expand Down
8 changes: 8 additions & 0 deletions Packs/Gmail/ReleaseNotes/1_3_29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

#### Integrations

##### Gmail

Fixed an issue where the following commands failed to decode the **htmlBody** argument if it was provided with no padding:
- ***send-mail***
- ***reply-mail***
2 changes: 1 addition & 1 deletion Packs/Gmail/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Gmail",
"description": "Gmail API and user management (This integration replaces the Gmail functionality in the GoogleApps API and G Suite integration).",
"support": "xsoar",
"currentVersion": "1.3.28",
"currentVersion": "1.3.29",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ def handle_html(self, htmlBody):
attachment = {
'maintype': maintype,
'subtype': subtype,
'data': base64.b64decode(m.group(3)),
'data': b64_decode(m.group(3)),
'name': name,
'cid': cid,
'ID': cid
Expand Down
8 changes: 8 additions & 0 deletions Packs/GmailSingleUser/ReleaseNotes/1_4_9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

#### Integrations

##### Gmail Single User

Fixed an issue where the following commands failed to decode the **htmlBody** argument if it was provided with no padding:
- ***send-mail***
- ***reply-mail***
2 changes: 1 addition & 1 deletion Packs/GmailSingleUser/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Gmail Single User",
"description": "Gmail API using OAuth 2.0.",
"support": "xsoar",
"currentVersion": "1.4.8",
"currentVersion": "1.4.9",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ def send_email_to_mailbox(account, to, subject, body, body_type, bcc, cc, reply_
return m


def handle_html(html_body) -> tuple[str, List[Dict[str, Any]]]:
def handle_html(html_body: str) -> tuple[str, List[Dict[str, Any]]]:
"""
Extract all data-url content from within the html and return as separate attachments.
Due to security implications, we support only images here
Expand All @@ -618,12 +618,11 @@ def handle_html(html_body) -> tuple[str, List[Dict[str, Any]]]:
name = f'image{i}'
cid = (f'{name}_{str(uuid.uuid4())[:8]}_{str(uuid.uuid4())[:8]}')
attachment = {
'data': base64.b64decode(m.group(3)),
'data': b64_decode(m.group(3)),
'name': name

}
attachment['cid'] = cid
clean_body += html_body[last_index:m.start(1)] + 'cid:' + attachment['cid']
clean_body += html_body[last_index:m.start(1)] + 'cid:' + str(attachment['cid'])
last_index = m.end() - 1
new_attachment = FileAttachment(name=attachment.get('name'), content=attachment.get('data'),
content_id=attachment.get('cid'), is_inline=True)
Expand Down
6 changes: 6 additions & 0 deletions Packs/MicrosoftExchangeOnPremise/ReleaseNotes/2_1_16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### EWS v2

Fixed an issue where the ***send-mail*** command failed to decode the **htmlBody** argument if it was provided with no padding.
2 changes: 1 addition & 1 deletion Packs/MicrosoftExchangeOnPremise/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Microsoft Exchange On-Premise",
"description": "Exchange Web Services",
"support": "xsoar",
"currentVersion": "2.1.15",
"currentVersion": "2.1.16",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ def handle_html(html_body) -> tuple[str, List[Dict[str, Any]]]:
name = f'image{i}'
cid = (f'{name}@{str(uuid.uuid4())[:8]}_{str(uuid.uuid4())[:8]}')
attachment = {
'data': base64.b64decode(m.group(3)),
'data': b64_decode(m.group(3)),
'name': name
}
attachment['cid'] = cid
Expand Down
8 changes: 8 additions & 0 deletions Packs/MicrosoftExchangeOnline/ReleaseNotes/1_5_18.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

#### Integrations

##### EWS O365

Fixed an issue where the following commands failed to decode the **htmlBody** argument if it was provided with no padding:
- ***send-mail***
- ***reply-mail***
2 changes: 1 addition & 1 deletion Packs/MicrosoftExchangeOnline/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Microsoft Exchange Online",
"description": "Exchange Online and Office 365 (mail)",
"support": "xsoar",
"currentVersion": "1.5.17",
"currentVersion": "1.5.18",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
18 changes: 18 additions & 0 deletions Packs/MicrosoftGraphMail/ReleaseNotes/1_6_20.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

#### Integrations

##### Microsoft Graph Mail Single User

Fixed an issue where the following commands failed to decode Base64-encoded attachments or images inside the html body when provided without padding:
- ***send-mail***
- ***reply-mail***
- ***msgraph-mail-get-attachment***
- ***fetch-incidents***

##### O365 Outlook Mail (Using Graph API)

Fixed an issue where the following commands failed to decode Base64-encoded attachments or images inside the html body when provided without padding:
- ***send-mail***
- ***reply-mail***
- ***msgraph-mail-get-attachment***
- ***fetch-incidents***
2 changes: 1 addition & 1 deletion Packs/MicrosoftGraphMail/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Microsoft Graph Mail",
"description": "Microsoft Graph lets your app get authorized access to a user's Outlook mail data in a personal or organization account.",
"support": "xsoar",
"currentVersion": "1.6.19",
"currentVersion": "1.6.20",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Loading