@@ -47,6 +47,85 @@ def test_filter_match(query, keywords, expected):
4747 assert f .match (keywords ) == expected
4848
4949
50+ @pytest .mark .parametrize (
51+ "malicious_query,keywords" ,
52+ [
53+ # Code injection attempts that would work with eval()
54+ ("__import__('os').system('echo pwned')" , ["test" ]),
55+ ("exec('import os; os.system(\" ls\" )')" , ["test" ]),
56+ ("eval('1+1')" , ["test" ]),
57+ ("__builtins__.__import__('os').system('ls')" , ["test" ]),
58+ # Attribute access attempts
59+ ("keywords.__class__.__bases__[0].__subclasses__()" , ["test" ]),
60+ # Lambda injection
61+ ("(lambda: __import__('os').system('ls'))()" , ["test" ]),
62+ # Dict/list comprehension injection
63+ ("[x for x in ().__class__.__bases__[0].__subclasses__()]" , ["test" ]),
64+ # Function call injection
65+ ("open('/etc/passwd').read()" , ["test" ]),
66+ # Module access
67+ ("sys.exit()" , ["test" ]),
68+ ("os.system('ls')" , ["test" ]),
69+ ],
70+ )
71+ def test_filter_blocks_code_injection (malicious_query , keywords ):
72+ """Test that malicious code injection attempts are safely handled."""
73+ f = _Filter (malicious_query )
74+ # Should not execute code, just return False for non-matching patterns
75+ result = f .match (keywords )
76+ assert isinstance (result , bool )
77+ # The filter should safely fail to match rather than execute code
78+ assert result is False
79+
80+
81+ @pytest .mark .parametrize (
82+ "injection_query" ,
83+ [
84+ # Various eval-based injection patterns
85+ "'; __import__('os').system('ls'); '" ,
86+ "\" ; exec('import os'); \" " ,
87+ "') or __import__('os').system('ls') or ('" ,
88+ # Nested injection attempts
89+ "test AND (__import__('os').system('ls'))" ,
90+ "NOT (__import__('subprocess').call(['ls']))" ,
91+ # String escape attempts
92+ "test' + str(__import__('os').system('ls')) + '" ,
93+ ],
94+ )
95+ def test_filter_injection_variants (injection_query ):
96+ """Test various code injection patterns are blocked."""
97+ f = _Filter (injection_query )
98+ result = f .match (["test" , "keyword" ])
99+ assert isinstance (result , bool )
100+ # Should not raise exceptions or execute code
101+ assert result in [True , False ]
102+
103+
104+ def test_filter_no_eval_execution ():
105+ """Verify that expressions are parsed safely without eval()."""
106+ # This would execute code if eval() was used
107+ dangerous_expr = "__import__('sys').exit(1)"
108+ f = _Filter (dangerous_expr )
109+
110+ # Should not crash the program or execute the exit
111+ result = f .match (["test" ])
112+ assert result is False
113+
114+
115+ def test_filter_safe_ast_parsing ():
116+ """Test that the filter uses AST parsing instead of eval()."""
117+ f = _Filter ("test AND keyword" )
118+
119+ # Verify AST is created
120+ assert f ._ast is None # Not parsed yet
121+ f .match (["test" , "keyword" ])
122+ assert f ._ast is not None # AST created after first match
123+
124+ # Verify it's an AST node, not a string for eval
125+ from sagemaker .core .jumpstart .search import _ExpressionNode
126+ assert isinstance (f ._ast , _ExpressionNode )
127+
128+
50129def test_search_public_hub_models ():
51130 mock_models = [
52131 HubContent (
0 commit comments