first commit

This commit is contained in:
Suherdy Yacob 2026-05-11 13:08:46 +07:00
commit f63dfd6c09
6 changed files with 74 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
__pycache__/
*.pyc
*.pyo
*.pyd
.swp
.DS_Store

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# HTTP Routing Safe URL
Prevent Odoo 19 from crashing when handling URLs containing dot segments (path traversal attempts).
## Problem
In Odoo 19, the utility `tools.urls.urljoin` was updated with strict validation that raises a `ValueError` if any path component contains a dot segment (`.` or `..`).
This causes a server-wide crash (500 Error) whenever a request hits a URL with these segments (e.g., bot probes like `example.com/../`), because the Odoo Website module tries to generate a canonical URL during error handling. Instead of a clean 404 page, the user sees a server error.
## Solution
This module patches `IrHttp._url_localized` to detect and resolve dot segments using `urllib.parse.urljoin` before they are passed to the strict Odoo utility. This allows Odoo to handle these requests gracefully (returning a 404) instead of crashing.
## Features
- Detects dot segments in URLs (including encoded variants like `%2e`).
- Resolves segments to a clean path (e.g., `/fr/../shop` becomes `/shop`).
- Prevents `ValueError: Dot segments are not allowed` tracebacks in logs.
## Installation
1. Install this module in your Odoo 19 database.
2. No further configuration is required.

1
__init__.py Normal file
View File

@ -0,0 +1 @@
from . import models

17
__manifest__.py Normal file
View File

@ -0,0 +1,17 @@
{
'name': 'HTTP Routing Safe URL',
'version': '19.0.1.0.0',
'summary': 'Prevent crash on URLs with dot segments',
'description': """
This module patches IrHttp._url_localized to sanitize URLs containing dot segments (. or ..).
Strict validation in odoo.tools.urls.urljoin raises ValueError for these segments,
which can cause crashes during error handling or canonical URL generation.
""",
'author': 'Suherdy Yacob',
'category': 'Website',
'depends': ['http_routing'],
'data': [],
'installable': True,
'auto_install': False,
'license': 'LGPL-3',
}

1
models/__init__.py Normal file
View File

@ -0,0 +1 @@
from . import ir_http

29
models/ir_http.py Normal file
View File

@ -0,0 +1,29 @@
import urllib.parse
from odoo import models
from odoo.http import request
class IrHttp(models.AbstractModel):
_inherit = 'ir.http'
@classmethod
def _url_localized(cls, url=None, **kwargs):
"""
Sanitize the URL to resolve dot segments before passing it to the base
implementation. This prevents a ValueError in tools.urls.urljoin
when canonical_domain is set.
"""
if url is None and request:
qs = request.httprequest.query_string.decode('utf-8')
url = request.httprequest.path + ('?%s' % qs if qs else '')
if url:
path, sep, qs = url.partition('?')
# Check for dot segments (. or ..) in the path
# urllib.parse.unquote is used to catch encoded segments like %2e
decoded_path = urllib.parse.unquote(path, errors='strict')
if any(seg in ('.', '..') for seg in decoded_path.split('/')):
# Resolve dot segments using urllib.parse.urljoin relative to root
path = urllib.parse.urljoin('/', path)
url = path + sep + qs
return super()._url_localized(url=url, **kwargs)