@@ -78,16 +78,48 @@ def _is_cloud_url(url: str) -> bool:
78
78
url: The URL to validate
79
79
80
80
Returns:
81
- bool: True if the URL is a valid Confluence Cloud URL
81
+ bool: True if the URL is a valid Confluence Cloud URL, False otherwise
82
+
83
+ Security:
84
+ This method implements strict URL validation:
85
+ - Only allows http:// and https:// schemes
86
+ - Properly validates domain names using full hostname matching
87
+ - Prevents common URL parsing attacks
82
88
"""
83
- parsed = urlparse (url )
84
- # Ensure we have a valid URL with a hostname
85
- if not parsed .hostname :
89
+ try :
90
+ parsed = urlparse (url )
91
+
92
+ # Validate scheme
93
+ if parsed .scheme not in ('http' , 'https' ):
94
+ return False
95
+
96
+ # Ensure we have a valid hostname
97
+ if not parsed .hostname :
98
+ return False
99
+
100
+ # Convert to lowercase for comparison
101
+ hostname = parsed .hostname .lower ()
102
+
103
+ # Split hostname into parts and validate
104
+ parts = hostname .split ('.' )
105
+
106
+ # Must have at least 3 parts (e.g., site.atlassian.net)
107
+ if len (parts ) < 3 :
108
+ return False
109
+
110
+ # Check exact matches for allowed domains
111
+ # This prevents attacks like: evil.com?atlassian.net
112
+ # or malicious-atlassian.net.evil.com
113
+ if hostname .endswith ('.atlassian.net' ):
114
+ return hostname == f"{ parts [- 3 ]} .atlassian.net"
115
+ elif hostname .endswith ('.jira.com' ):
116
+ return hostname == f"{ parts [- 3 ]} .jira.com"
117
+
86
118
return False
87
119
88
- # Check if the hostname ends with .atlassian.net or .jira.com
89
- hostname = parsed . hostname . lower ()
90
- return hostname . endswith ( '.atlassian.net' ) or hostname . endswith ( '.jira.com' )
120
+ except Exception :
121
+ # Any parsing error means invalid URL
122
+ return False
91
123
92
124
def __init__ (
93
125
self ,
0 commit comments