|
13 | 13 | ) |
14 | 14 |
|
15 | 15 |
|
| 16 | +def _has_module(module_name: str) -> bool: |
| 17 | + code = f""" |
| 18 | + {module_name}.is_available() |
| 19 | + """ |
| 20 | + parser = ExpressionsParser() |
| 21 | + interpreter = ExpressionsInterpreter() |
| 22 | + tree = parser.parse(code) |
| 23 | + return interpreter.execute(tree) |
| 24 | + |
| 25 | + |
16 | 26 | def test_security_checks(): |
17 | 27 | """Test comprehensive security checks in the interpreter. |
18 | 28 |
|
@@ -135,6 +145,30 @@ def test_forbidden_module_access(): |
135 | 145 | interpreter.execute(tree) |
136 | 146 |
|
137 | 147 |
|
| 148 | +@pytest.mark.skipif(not _has_module("pd"), reason="Pandas is not available") |
| 149 | +def test_forbidden_module_indirect_access(): |
| 150 | + """Test forbidden module access in indirect ways. |
| 151 | +
|
| 152 | + Tests: |
| 153 | + 1. Access to pickle via pandas |
| 154 | + 2. Access to io via pandas |
| 155 | + """ |
| 156 | + parser = ExpressionsParser() |
| 157 | + interpreter = ExpressionsInterpreter() |
| 158 | + |
| 159 | + # Test pickle access via pandas |
| 160 | + with pytest.raises( |
| 161 | + SecurityError, match="Access to 'pickle' is not allowed" |
| 162 | + ): |
| 163 | + tree = parser.parse("pd.io.pickle.pickle.codecs") |
| 164 | + interpreter.execute(tree) |
| 165 | + |
| 166 | + # Test pickle access via pandas |
| 167 | + with pytest.raises(SecurityError, match="Access to 'io' is not allowed"): |
| 168 | + tree = parser.parse("pd.io.pickle.pc.io.abc") |
| 169 | + interpreter.execute(tree) |
| 170 | + |
| 171 | + |
138 | 172 | def test_forbidden_builtins_access(): |
139 | 173 | """Test forbidden builtins access in more detail. |
140 | 174 |
|
|
0 commit comments