Skip to content
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
20 changes: 13 additions & 7 deletions src/exploit_iq_commons/utils/string_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@
# Find all substrings that start and end with quotes, allowing for spaces before a comma or closing bracket
re_quote_capture = re.compile(
r"""
(['"]) # Opening quote
( # Start capturing the quoted content
(?:\\.|[^\\])*? # Non-greedy match for any escaped character or non-backslash character
) # End capturing the quoted content
\1 # Matching closing quote
(?=\s*,|\s*\]) # Lookahead for whitespace followed by a comma or closing bracket, without including it in the match
(['"]) # Group 1: Opening quote
( # Group 2: Content
(?:
# Match anything UNLESS it is the specific outer list separator.
# Outer separator = quote + comma + space + quote + CAPITAL LETTER.
# OR it is the closing bracket at the very end of the string.
(?!\1\s*,\s*\1\s*[A-Z]|\1\s*\]\s*$)
.
)*
)
\1 # Closing quote
(?=\s*[,\]]) # Lookahead for comma or closing bracket
""",
re.VERBOSE)
re.VERBOSE | re.DOTALL)

# Using the ASCII flag to stricly match numbers 0-9 and not on unicode numbers which include characters like ٤.
# https://cve.mitre.org/cve/identifiers/syntaxchange.html
Expand Down
93 changes: 93 additions & 0 deletions src/vuln_analysis/utils/tests/test_checklist_prompt_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import pytest
import logging
logger = logging.getLogger(__name__)

from vuln_analysis.utils.checklist_prompt_generator import _parse_list

line1 = '"Is the `USER $USERNAME` Dockerfile instruction used in the container image, potentially allowing an attacker to manipulate supplementary group access?",'
line2 = '"Are there any instances of `ENTRYPOINT ["su", "-", "user"]` in the Dockerfile, which could indicate a safer alternative to setting up supplementary groups?",'
line3 = '"Does the container image run with a user that has elevated privileges, potentially increasing the risk of exploiting supplementary group mishandling?",'
line4 = '"Are there any sensitive files or directories within the container that could be accessed by an attacker if they were to bypass primary group restrictions using supplementary group access?",'
line5 = '"Does the container\'s configuration or Dockerfile explicitly set or modify supplementary groups, which could impact the vulnerability\'s exploitability?"'
list1_as_string = f"[{line1}{line2}{line3}{line4}{line5}]"
list2_as_string_with_newlines = f"[{line1}\n{line2}\n{line3}\n{line4}\n{line5}]"

expected_line1 = "Is the `USER $USERNAME` Dockerfile instruction used in the container image, potentially allowing an attacker to manipulate supplementary group access?"
expected_line2 = "Are there any instances of `ENTRYPOINT [\"su\", \"-\", \"user\"]` in the Dockerfile, which could indicate a safer alternative to setting up supplementary groups?"
expected_line3 = "Does the container image run with a user that has elevated privileges, potentially increasing the risk of exploiting supplementary group mishandling?"
expected_line4 = "Are there any sensitive files or directories within the container that could be accessed by an attacker if they were to bypass primary group restrictions using supplementary group access?"
expected_line5 = "Does the container\'s configuration or Dockerfile explicitly set or modify supplementary groups, which could impact the vulnerability\'s exploitability?"

@pytest.mark.asyncio
async def test_parse_single_with_none_escaped_quotes_without_newlines():
result = await _parse_list([list1_as_string])
assert result[0][0] == expected_line1
assert result[0][1] == expected_line2
assert result[0][2] == expected_line3
assert result[0][3] == expected_line4
assert result[0][4] == expected_line5

@pytest.mark.asyncio
async def test_parse_single_with_none_escaped_quotes_with_newlines():
result = await _parse_list([list2_as_string_with_newlines])
assert result[0][0] == expected_line1
assert result[0][1] == expected_line2
assert result[0][2] == expected_line3
assert result[0][3] == expected_line4
assert result[0][4] == expected_line5

@pytest.mark.asyncio
async def test_parse_single_with_backslashes():
input_backslashes = r"""
[
"Are there any instances of `ENTRYPOINT ["su", "-", "user"]` in the Dockerfile, which could indicate a safer alternative to setting up supplementary groups?",
"Does \ the container's configuration or Dockerfile explicitly set or modify supplementary groups, which could impact the vulnerability's exploitability?"
]
"""
expected_line2 = "Does \\ the container's configuration or Dockerfile explicitly set or modify supplementary groups, which could impact the vulnerability's exploitability?"
result = await _parse_list([input_backslashes])
assert result[0][1] == expected_line2


@pytest.mark.asyncio
async def test_parse_single_with_backslashes_n():
input_backslashes_with_newline = """
[
"line1 with \nnewlines"
]
"""
expected_line1 = "line1 with newlines"
result = await _parse_list([input_backslashes_with_newline])
assert result[0][0] == expected_line1

@pytest.mark.asyncio
async def test_parse_single_with_backslashes_t():
char_line = r"line1 with \tchar"
char_line_none_raw = "line1 with \tchar"
input_backslashes_list = "[\"" + char_line + "\"]"
result = await _parse_list([input_backslashes_list])
assert repr(result[0][0]) == repr(char_line_none_raw)

@pytest.mark.asyncio
async def test_parse_single_with_backslashes_f():
char_line = r"line1 with \fchar"
char_line_none_raw = "line1 with \fchar"
input_backslashes_list = "[\"" + char_line + "\"]"
result = await _parse_list([input_backslashes_list])
assert repr(result[0][0]) == repr(char_line_none_raw)

@pytest.mark.asyncio
async def test_parse_single_with_backslashes_b():
char_line = r"line1 with \bchar"
char_line_none_raw = "line1 with \bchar"
input_backslashes_list = "[\"" + char_line + "\"]"
result = await _parse_list([input_backslashes_list])
assert repr(result[0][0]) == repr(char_line_none_raw)

@pytest.mark.asyncio
async def test_parse_single_with_backslashes_backslash():
char_line = r"line1 with \ char"
char_line_none_raw = "line1 with \\ char"
input_backslashes_list = "[\"" + char_line + "\"]"
result = await _parse_list([input_backslashes_list])
assert repr(result[0][0]) == repr(char_line_none_raw)
Loading