Skip to content

πŸ›‘οΈ Sentinel: Fix broken validation and add length limits#425

Closed
abhimehro wants to merge 1 commit intomainfrom
sentinel-fix-validation-limits-11441188995627958754
Closed

πŸ›‘οΈ Sentinel: Fix broken validation and add length limits#425
abhimehro wants to merge 1 commit intomainfrom
sentinel-fix-validation-limits-11441188995627958754

Conversation

@abhimehro
Copy link
Owner

🚨 Severity: HIGH
πŸ’‘ Vulnerability:

  1. validate_folder_data contained invalid syntax, causing the application to crash or fail validation silently (Availability).
  2. Input validation lacked length limits for folder names, IDs, and rules, allowing potential DoS via memory exhaustion or large payloads.
  3. push_rules optimization bypassed the standard is_valid_rule check.

🎯 Impact:

  • Application instability (crash on certain inputs).
  • Potential Denial of Service (DoS) via large inputs.

πŸ”§ Fix:

  • Repaired syntax error in validate_folder_data and restored proper validation logic.
  • Added length limits: Folder IDs/Names (64 chars), Rules (255 chars).
  • Updated push_rules to respect the new length limit inline.

βœ… Verification:

  • Added tests/test_security_limits.py to verify length constraints.
  • Ran full test suite (172 tests passed).

PR created automatically by Jules for task 11441188995627958754 started by @abhimehro

- Fixed syntax error in `validate_folder_data` that prevented execution.
- Added input length limits to prevent DoS:
  - Folder IDs: max 64 chars
  - Folder Names: max 64 chars
  - Rules: max 255 chars
- Updated `push_rules` to enforce rule length limit (previously bypassed standard validation).
- Added tests in `tests/test_security_limits.py`.

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
@google-labs-jules
Copy link

πŸ‘‹ Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a πŸ‘€ emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings February 25, 2026 10:43
@trunk-io
Copy link

trunk-io bot commented Feb 25, 2026

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

@github-actions
Copy link

πŸ‘‹ Development Partner is reviewing this PR. Will provide feedback shortly.

@gemini-code-assist
Copy link

Summary of Changes

Hello @abhimehro, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses critical security vulnerabilities by fixing a broken validation function and implementing comprehensive length limits across various input fields. The changes enhance application stability, prevent potential Denial of Service attacks, and ensure that security controls are consistently applied, even in optimized code paths. The introduction of new tests verifies the effectiveness of these security improvements.

Highlights

  • Validation Fix: Repaired a critical syntax error in validate_folder_data that was causing silent validation failures or application crashes, restoring proper data validation.
  • Length Limits Implemented: Introduced strict length limits for folder IDs (64 characters), folder names (64 characters), and rules (255 characters) to mitigate potential Denial of Service (DoS) attacks via memory exhaustion or large payloads.
  • Security Bypass Prevention: Updated the push_rules function to explicitly incorporate the new rule length limit, preventing a potential security control bypass that could occur due to an optimized, inline regex check.
  • New Test Coverage: Added a new test file, tests/test_security_limits.py, to specifically verify the newly implemented length constraints for folder names, IDs, and rules.
Changelog
  • .jules/sentinel.md
    • Documented a new security learning entry regarding how performance optimizations can inadvertently bypass security controls if not carefully managed.
  • main.py
    • Enforced a maximum length of 64 characters for folder IDs within the validate_folder_id function.
    • Introduced a maximum length of 255 characters for rules in is_valid_rule to prevent potential DoS attacks.
    • Applied a maximum length of 64 characters for folder names in the is_valid_folder_name function.
    • Fixed syntax errors and corrected indentation in validate_folder_data to ensure proper validation of rule groups and individual rules.
    • Integrated the 255-character length check directly into push_rules to prevent security bypasses and ensure consistent validation.
  • tests/test_security_limits.py
    • Added test_is_valid_folder_name_limits to verify folder name length validation.
    • Added test_is_valid_rule_limits to verify rule length validation.
    • Added test_validate_folder_id_limits to verify folder ID length validation.
Activity
  • PR created automatically by Jules for task 11441188995627958754.
  • Full test suite (172 tests) was run and passed, verifying the changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with πŸ‘ and πŸ‘Ž on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩


def test_is_valid_folder_name_limits():
# Test length limit: 64 characters (pass)
assert main.is_valid_folder_name("a" * 64) is True

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.is_valid_folder_name("a" * 64) is True

# Test length limit: 65 characters (fail)
assert main.is_valid_folder_name("a" * 65) is False

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
def test_is_valid_rule_limits():
# Test length limit: 255 characters (pass)
# Using 'a' which matches the regex ^[a-zA-Z0-9.\-_:*/@]+$
assert main.is_valid_rule("a" * 255) is True

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.is_valid_rule("a" * 255) is True

# Test length limit: 256 characters (fail)
assert main.is_valid_rule("a" * 256) is False

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
def test_validate_folder_id_limits():
# Test length limit: 64 characters (pass)
# Using 'a' which matches ^[a-zA-Z0-9_.-]+$
assert main.validate_folder_id("a" * 64) is True

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Test length limit: 65 characters (fail)
# We pass log_errors=False to avoid cluttering output
assert main.validate_folder_id("a" * 65, log_errors=False) is False

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
return False
if len(folder_id) > 64:
if log_errors:
log.error(f"Invalid folder ID length (max 64): {len(folder_id)}")

Check warning

Code scanning / Prospector (reported by Codacy)

Use lazy % formatting in logging functions (logging-fstring-interpolation) Warning

Use lazy % formatting in logging functions (logging-fstring-interpolation)
@@ -0,0 +1,27 @@
import pytest

Check warning

Code scanning / Prospector (reported by Codacy)

Unable to import 'pytest' (import-error) Warning test

Unable to import 'pytest' (import-error)
@@ -0,0 +1,27 @@
import pytest

Check warning

Code scanning / Prospector (reported by Codacy)

Unused import pytest (unused-import) Warning test

Unused import pytest (unused-import)
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check warning

Code scanning / Prospector (reported by Codacy)

Unused MagicMock imported from unittest.mock (unused-import) Warning test

Unused MagicMock imported from unittest.mock (unused-import)
main.py Outdated

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (120/100) Warning

Line too long (120/100)
@@ -0,0 +1,27 @@
import pytest

Check warning

Code scanning / Pylint (reported by Codacy)

Missing module docstring Warning test

Missing module docstring
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check warning

Code scanning / Pylint (reported by Codacy)

standard import "from unittest.mock import MagicMock, patch" should be placed before "import pytest" Warning test

standard import "from unittest.mock import MagicMock, patch" should be placed before "import pytest"
from unittest.mock import MagicMock, patch
import main

def test_is_valid_folder_name_limits():

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning test

Missing function docstring
# Test length limit: 65 characters (fail)
assert main.is_valid_folder_name("a" * 65) is False

def test_is_valid_rule_limits():

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning test

Missing function docstring
# Test length limit: 256 characters (fail)
assert main.is_valid_rule("a" * 256) is False

def test_validate_folder_id_limits():

Check warning

Code scanning / Pylint (reported by Codacy)

Missing function docstring Warning test

Missing function docstring
@@ -0,0 +1,27 @@
import pytest

Check notice

Code scanning / Pylint (reported by Codacy)

Unused import pytest Note test

Unused import pytest
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check notice

Code scanning / Pylint (reported by Codacy)

Unused MagicMock imported from unittest.mock Note test

Unused MagicMock imported from unittest.mock
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check notice

Code scanning / Pylint (reported by Codacy)

Unused patch imported from unittest.mock Note test

Unused patch imported from unittest.mock

def test_is_valid_folder_name_limits():
# Test length limit: 64 characters (pass)
assert main.is_valid_folder_name("a" * 64) is True

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.is_valid_folder_name("a" * 64) is True

# Test length limit: 65 characters (fail)
assert main.is_valid_folder_name("a" * 65) is False

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
def test_is_valid_rule_limits():
# Test length limit: 255 characters (pass)
# Using 'a' which matches the regex ^[a-zA-Z0-9.\-_:*/@]+$
assert main.is_valid_rule("a" * 255) is True

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert main.is_valid_rule("a" * 255) is True

# Test length limit: 256 characters (fail)
assert main.is_valid_rule("a" * 256) is False

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
def test_validate_folder_id_limits():
# Test length limit: 64 characters (pass)
# Using 'a' which matches ^[a-zA-Z0-9_.-]+$
assert main.validate_folder_id("a" * 64) is True

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Test length limit: 65 characters (fail)
# We pass log_errors=False to avoid cluttering output
assert main.validate_folder_id("a" * 65, log_errors=False) is False

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
main.py Outdated

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (120/100) Warning

Line too long (120/100)
@@ -0,0 +1,27 @@
import pytest

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing module docstring Warning test

Missing module docstring
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

standard import "from unittest.mock import MagicMock, patch" should be placed before "import pytest" Warning test

standard import "from unittest.mock import MagicMock, patch" should be placed before "import pytest"
from unittest.mock import MagicMock, patch
import main

def test_is_valid_folder_name_limits():

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning test

Missing function or method docstring
# Test length limit: 65 characters (fail)
assert main.is_valid_folder_name("a" * 65) is False

def test_is_valid_rule_limits():

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning test

Missing function or method docstring
# Test length limit: 256 characters (fail)
assert main.is_valid_rule("a" * 256) is False

def test_validate_folder_id_limits():

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing function or method docstring Warning test

Missing function or method docstring
return False
if len(folder_id) > 64:
if log_errors:
log.error(f"Invalid folder ID length (max 64): {len(folder_id)}")

Check notice

Code scanning / Pylintpython3 (reported by Codacy)

Use lazy % formatting in logging functions Note

Use lazy % formatting in logging functions
@@ -0,0 +1,27 @@
import pytest

Check notice

Code scanning / Pylintpython3 (reported by Codacy)

Unused import pytest Note test

Unused import pytest
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check notice

Code scanning / Pylintpython3 (reported by Codacy)

Unused MagicMock imported from unittest.mock Note test

Unused MagicMock imported from unittest.mock
@@ -0,0 +1,27 @@
import pytest
from unittest.mock import MagicMock, patch

Check notice

Code scanning / Pylintpython3 (reported by Codacy)

Unused patch imported from unittest.mock Note test

Unused patch imported from unittest.mock
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses validation-related security and stability issues by repairing validate_folder_data syntax/logic, adding input length limits to reduce DoS risk, and extending test coverage to enforce these limits.

Changes:

  • Add max-length constraints for folder IDs/names (64) and rules (255) in validation helpers.
  • Fix broken validate_folder_data logic and ensure it returns True on success.
  • Add a new security-focused test module covering the new length limits.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
main.py Adds length limits to validators, fixes validate_folder_data, and updates push_rules filtering logic.
tests/test_security_limits.py Introduces tests that assert folder/rule length constraints are enforced.
.jules/sentinel.md Documents the optimization/validation drift risk as a Sentinel entry.

Comment on lines +1 to +2
import pytest
from unittest.mock import MagicMock, patch
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pytest, MagicMock, and patch are imported but not used in this test module. Removing unused imports will keep the test file minimal and avoid implying mocks/fixtures are required here.

Suggested change
import pytest
from unittest.mock import MagicMock, patch

Copilot uses AI. Check for mistakes.
Comment on lines 1992 to +2002
# Optimization 2: Inline regex match and check existence
# Using a local reference to the match method avoids function call overhead
# in the hot loop. This provides a measurable speedup for large lists.
match_rule = RULE_PATTERN.match

for h in unique_hostnames:
if h in existing_rules:
continue

if not match_rule(h):
# Enforce max length (255) and regex pattern
if len(h) > 255 or not match_rule(h):
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

push_rules still duplicates the canonical rule-validation logic (length + RULE_PATTERN.match) instead of reusing is_valid_rule. This can drift again if is_valid_rule gains additional checks; consider calling is_valid_rule(h) (optionally via a local alias for performance) and/or centralizing the max-length value in a shared constant used by both paths.

Copilot uses AI. Check for mistakes.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses several security vulnerabilities by fixing broken validation logic in validate_folder_data and introducing much-needed length limits for various inputs to prevent potential Denial of Service attacks. The changes are well-documented and include new tests to verify the added constraints. My feedback focuses on improving the long-term maintainability of these new security limits by suggesting the use of named constants instead of hardcoded 'magic numbers', which will make the code safer and easier to manage.

"""Validates folder ID (PK) format to prevent path traversal."""
if not folder_id:
return False
if len(folder_id) > 64:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The value 64 is used as a maximum length for folder IDs here, and also for folder names (is_valid_folder_name) and profile IDs (is_valid_profile_id_format). To improve maintainability and ensure these security-related limits are consistent, consider defining a module-level constant (e.g., MAX_ID_LENGTH = 64) and using it in all relevant validation functions.

return False

# Enforce max length to prevent DoS
if len(rule) > 255:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The maximum rule length 255 is hardcoded here and also in push_rules. To prevent potential drift between this canonical validation function and the inlined performance optimization (as noted in .jules/sentinel.md), it's best to define this value as a module-level constant (e.g., MAX_RULE_LENGTH = 255) and use it in both places. This will make the code safer and easier to maintain.

return False

# Enforce max length to prevent DoS (matching profile ID limit)
if len(name) > 64:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The value 64 is used as a maximum length here and in other validation functions. To improve maintainability and ensure these security-related limits are consistent, consider defining a module-level constant (e.g., MAX_NAME_LENGTH = 64) and using it across all relevant functions.


if not match_rule(h):
# Enforce max length (255) and regex pattern
if len(h) > 255 or not match_rule(h):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The maximum rule length 255 is hardcoded here, duplicating the value from is_valid_rule. To prevent potential logic drift between this optimized path and the canonical validation function (a risk highlighted in .jules/sentinel.md), it would be safer to use a shared module-level constant (e.g., MAX_RULE_LENGTH = 255) in both places.

@abhimehro
Copy link
Owner Author

πŸ€– Automated PR Review β€” Closing as duplicate

This combines the syntax fix with input length limits. #412 already provides dedicated input length limits against DoS, and the syntax fix should be applied cleanly to main without bundling. Closing as superseded by #412.

@google-labs-jules
Copy link

πŸ€– Automated PR Review β€” Closing as duplicate

This combines the syntax fix with input length limits. #412 already provides dedicated input length limits against DoS, and the syntax fix should be applied cleanly to main without bundling. Closing as superseded by #412.

Understood. Acknowledging that this work is superseded by #412 and stopping work on this task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants