mirror of
https://github.com/ansible/awx.git
synced 2026-10-31 14:36:17 -02:30
[AAP-78700] Add field level validations for source path traversal (#16637)
* Add field level validations for source path traversal * Reject absolute UNC and drive-qualified paths * Remove absolute path check
This commit is contained in:
+10
-1
@@ -128,7 +128,7 @@ from awx.api.versioning import reverse
|
||||
from awx.api.fields import BooleanNullField, CharNullField, ChoiceNullField, VerbatimField, DeprecatedCredentialField
|
||||
|
||||
# AWX Utils
|
||||
from awx.api.validators import HostnameRegexValidator
|
||||
from awx.api.validators import HostnameRegexValidator, contains_path_traversal
|
||||
|
||||
logger = logging.getLogger('awx.api.serializers')
|
||||
|
||||
@@ -2350,6 +2350,15 @@ class InventorySourceOptionsSerializer(BaseSerializer):
|
||||
res['credential'] = self.reverse('api:credential_detail', kwargs={'pk': obj.credential})
|
||||
return res
|
||||
|
||||
def validate_source_path(self, value):
|
||||
# Unchanged values on update are grandfathered so pre-existing traversal
|
||||
# paths are not rejected until they are edited (AAP-78700).
|
||||
if self.instance is not None and getattr(self.instance, 'source_path', None) == value:
|
||||
return value
|
||||
if contains_path_traversal(value):
|
||||
raise serializers.ValidationError(_("Enter a path that does not include '..' path segments."))
|
||||
return value
|
||||
|
||||
def validate_source_vars(self, value):
|
||||
ret = vars_validate_or_raise(value)
|
||||
for env_k in parse_yaml_or_json(value):
|
||||
|
||||
@@ -4,6 +4,18 @@ from django.core.validators import RegexValidator, validate_ipv46_address
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
|
||||
def contains_path_traversal(value):
|
||||
"""Return True if value contains a '..' path segment.
|
||||
|
||||
Matches POSIX (`../`) and Windows (`..\\`) traversal. A file name that
|
||||
merely contains two dots (e.g. `backup..yml`) is not traversal.
|
||||
Absolute paths are allowed; they are not parent-directory traversal.
|
||||
"""
|
||||
if not isinstance(value, str) or not value:
|
||||
return False
|
||||
return any(part == '..' for part in value.replace('\\', '/').split('/'))
|
||||
|
||||
|
||||
class HostnameRegexValidator(RegexValidator):
|
||||
"""
|
||||
Fully validates a domain name that is compliant with norms in Linux/RHEL
|
||||
|
||||
Reference in New Issue
Block a user