Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ existing tools and performs at any scale.
[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy/?template=https://github.com/baserow/baserow/tree/master)

```bash
docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.1.6
docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.2.0
```

![Baserow database screenshot](docs/assets/screenshot.png "Baserow database screenshot")
Expand Down Expand Up @@ -108,7 +108,7 @@ Created by Baserow B.V. - bram@baserow.io.

Distributes under the MIT license. See `LICENSE` for more information.

Version: 2.1.6
Version: 2.2.0

The official repository can be found at https://github.com/baserow/baserow.

Expand Down
2 changes: 1 addition & 1 deletion backend/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -euo pipefail
# ENVIRONMENT VARIABLES USED DIRECTLY BY THIS ENTRYPOINT
# ======================================================

export BASEROW_VERSION="2.1.6"
export BASEROW_VERSION="2.2.0"

# Used by docker-entrypoint.sh to start the dev server
# If not configured you'll receive this: CommandError: "0.0.0.0:" is not a valid port number or address:port pair.
Expand Down
2 changes: 1 addition & 1 deletion backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dynamic = ["version"]
classifiers = []

dependencies = [
"django==5.2.12",
"django==5.2.13",
"django-cors-headers==4.9.0",
"djangorestframework==3.16.1",
"djangorestframework-simplejwt==5.5.1",
Expand Down
2 changes: 1 addition & 1 deletion backend/src/baserow/config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@
"name": "MIT",
"url": "https://github.com/baserow/baserow/blob/develop/LICENSE",
},
"VERSION": "2.1.6",
"VERSION": "2.2.0",
"SERVE_INCLUDE_SCHEMA": False,
"TAGS": [
{"name": "Settings"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
TextField,
)
from baserow.core.psycopg import psycopg, sql
from baserow.core.utils import ChildProgressBuilder, are_hostnames_same
from baserow.core.utils import (
ChildProgressBuilder,
are_hostnames_same,
is_hostname_safe,
)

from .exceptions import SyncError
from .models import PostgreSQLDataSync
Expand Down Expand Up @@ -155,6 +159,9 @@ def _connection(self, instance):
cursor = None
connection = None

if not is_hostname_safe(instance.postgresql_host):
raise SyncError("It's not allowed to connect to this hostname.")

baserow_postgresql_connection = (
settings.BASEROW_PREVENT_POSTGRESQL_DATA_SYNC_CONNECTION_TO_DATABASE
and are_hostnames_same(
Expand Down
37 changes: 37 additions & 0 deletions backend/src/baserow/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import hashlib
import inspect
import io
import ipaddress
import math
import os
import random
Expand Down Expand Up @@ -1204,6 +1205,42 @@ def get_all_ips(hostname: str) -> Set:
return set()


def is_hostname_safe(hostname: str) -> bool:
"""
Checks if the hostname resolves only to safe addresses.

Unsafe addresses include:
- Wildcard (0.0.0.0, ::)
- Loopback (127.0.0.0/8, ::1)
- Link-local (169.254.0.0/16, fe80::/10)
- Reserved, multicast, etc.

:param hostname: The hostname to check.
:return: True if all resolved IPs are safe.
"""

ips = get_all_ips(hostname)
if not ips:
return False

for ip in ips:
try:
ip_obj = ipaddress.ip_address(ip)
except ValueError:
return False

if (
ip_obj.is_unspecified # wildcard
or ip_obj.is_loopback
or ip_obj.is_link_local
or ip_obj.is_multicast
or ip_obj.is_reserved
):
return False

return True


def are_hostnames_same(hostname1: str, hostname2: str) -> bool:
"""
Resolves the IP addresses of both hostnames, and checks they resolve to the same IP
Expand Down
2 changes: 1 addition & 1 deletion backend/src/baserow/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.1.6"
VERSION = "2.2.0"
27 changes: 27 additions & 0 deletions backend/tests/baserow/core/test_core_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
get_baserow_saas_base_url,
get_value_at_path,
grouper,
is_hostname_safe,
random_string,
remove_duplicates,
remove_invalid_surrogate_characters,
Expand Down Expand Up @@ -683,6 +684,32 @@ def test_remove_duplicates():

def test_get_all_ips():
assert get_all_ips("localhost") == {"127.0.0.1", "::1"}
assert get_all_ips("0.0.0.0") == {"0.0.0.0"} # noqa: S104
assert get_all_ips("::") == {"::"}


def test_is_hostname_safe():
# Public address (should be safe)
assert is_hostname_safe("12.33.56.1") is True

# Wildcard addresses are not considered safe
assert is_hostname_safe("0.0.0.0") is False # noqa: S104 IPv4 wildcard
assert is_hostname_safe("::") is False # IPv6 wildcard

# Loopback addresse sare not considered safe
assert is_hostname_safe("127.0.0.1") is False # IPv4 loopback
assert is_hostname_safe("::1") is False # IPv6 loopback

# Link-local addresses are not considered safe
assert is_hostname_safe("169.254.1.1") is False # IPv4 link-local
assert is_hostname_safe("fe80::1") is False # IPv6 link-local

# Multicast addresses are not considered safe
assert is_hostname_safe("224.0.0.1") is False # IPv4 multicast
assert is_hostname_safe("ff02::1") is False # IPv6 multicast

# Reserved addresses are not considered safe
assert is_hostname_safe("240.0.0.1") is False # IPv4 reserved


def test_are_hostnames_same():
Expand Down
12 changes: 6 additions & 6 deletions backend/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
# Changelog

## Released 2.2.0

### New features
* [Database] Add the `array_unique` formula function to deduplicate lookup arrays. [#2326](https://gitlab.com/baserow/baserow/-/issues/2326)
* [Builder] Allow to drag and drop element on the page [#3634](https://github.com/baserow/baserow/issues/3634)
* [Database] Introduced restricted view ownership type for view-level permissions. [#3673](https://github.com/baserow/baserow/issues/3673)
* [Automation] Support automation templates [#3871](https://github.com/baserow/baserow/issues/3871)
* [Core] Improved Baserow formula function argument validation. [#4532](https://github.com/baserow/baserow/issues/4532)
* [Database] Add the `array_slice` formula function to extract sub-arrays from lookup arrays. [#5053](https://gitlab.com/baserow/baserow/-/issues/5053)
* [Database] Add instance wide data scanner.
* [Database] Introduced field type that can edit a row via a form view. [#2287](https://github.com/baserow/baserow/issues/2287)
* [Database] Allow freezing (pinning) up to 4 columns on the left side of the grid view. [#2047](https://github.com/baserow/baserow/issues/2047)
* [Database] Generalize the `index` formula to work with any array type (not just file fields) and add `first` and `last` convenience functions. [#5065](https://gitlab.com/baserow/baserow/-/issues/5065)
* [Core] Introduced optional Cloudflare Turnstile captcha during signup.

### Bug fixes
* [Database] Fix index max size error for view sort indexes [#2040](https://github.com/baserow/baserow/issues/2040)
* [Database] Fix public view with hidden group by field [#4858](https://github.com/baserow/baserow/issues/4858)
* [Core] Switch to insecure alternative for UUID generation when on insecure context like HTTP [#4905](https://github.com/baserow/baserow/issues/4905)
* [Database] Rating field now doesn't accept 0 as a valid value in form views when the field is required [#4985](https://github.com/baserow/baserow/issues/4985)
* [Database] Fix DatatypeMismatch on bulk insert for tables with formula fields [#4992](https://github.com/baserow/baserow/issues/4992)
* [Database] Fix AIField generation for mistral API provider [#4994](https://github.com/baserow/baserow/issues/4994)
* [Automation] Fixed a bug that prevented reordering workflows in an automation. [#4995](https://github.com/baserow/baserow/issues/4995)
* [Automation] Removed a constraint that forced unique workflow names. [#4995](https://github.com/baserow/baserow/issues/4995)
* [Integration] Allow advanced formula for JSON body content of HTTP request node [#5002](https://github.com/baserow/baserow/issues/5002)
* [Database] Fix error when changing filter type on link row fields [#5014](https://github.com/baserow/baserow/issues/5014)
* [Database] Fix group by counts for link row field [#5047](https://github.com/baserow/baserow/issues/5047)
* [Core] Fix [nuxt] instance unavailable errors [#5063](https://github.com/baserow/baserow/issues/5063)
* [Database] Ensure primary field always exists on sync table [#5088](https://github.com/baserow/baserow/issues/5088)
* [Database] Fix autonumber sequence [#5115](https://github.com/baserow/baserow/issues/5115)
* [Core] Filter tokens by workspace membership [#5144](https://github.com/baserow/baserow/issues/5144)
* [Database] Fixed slow cleanup of row history table by adding a database index.
* [Builder] Data source context was not reset after a data source creation
* [Automation] Ensure known service errors are logged as warnings to reduce error monitoring noise.
* [Builder] Ensure that the correct error is shown when exceeding the max publish job count.
* [Builder] Ensure the correct error is shown when a page is not found.
* [Automation] Ensure the max publish job count error is shown when exceeding the limit for publishing an Automation Workflow.
* [Automation] Fix bad previous node result inside an iteration
* [Core] Fix date localization not working with non english languages
* [Database] Fix linked row modal checkbox
* [Automation] Fix race condition in loop handling
* [Database] Fix bug where it was not possible to open the row edit modal if the user did not have access to the related table.
* [Database] Fixed survey form navigation with required fields [#3188](https://github.com/baserow/baserow/issues/3188)
* [Integration] Fix the wrong from address changed by the email backend
* [Automation] Fixed a bug that caused a crash when trying to view an Automation's settings in development mode.
* [Builder] Fixed a bug where a broken List Rows data source could cause a crash.
* [Builder] Fixed a bug where an unknown timezone could cause a data source dispatch to fail.
* [Automation] Fixed a bug where automation workflow history entries were being deleted for running workflows.
* [Automation] Fixed a bug where node simulation errors weren't immediately shown.
* [Builder] Fixed a bug where reopening the Publish modal while the builder is still publishing can cause an error.
* [Builder] Fixed a crash when fetching custom code for a non-existent builder ID.
* [Builder] Fixed an unhandled error when a user source user logs out and their refresh token is already expired.
* [Integration] Fixed the Slack Bot Form's translations to use the correct placeholders.
* [Database] Forbid wildcard addresses in Postgres data sync
* [Automation] Resolved a bug which prevented certain Baserow field types from being used after a row-change trigger.
* [Database] Resolved an issue which caused AI field formulas to appear twice in the UI.

### Refactors
* [Database] Filter out unactionable AxiosErrors from sentry [#5008](https://github.com/baserow/baserow/issues/5008)
* [Core] Silence defined error codes in Sentry [#5011](https://github.com/baserow/baserow/issues/5011)
* [Core] Add affected users count to frontend sentry reports [#5028](https://github.com/baserow/baserow/issues/5028)
* [Core] Harden workspace import ZIP extraction against malformed archives [#5111](https://github.com/baserow/baserow/issues/5111)
* [Core] Replace udspy with pydantic-ai
* [Database] Optimized table deletion (trash) by batching field operations.
* [Core] refactor MCP tools; share AI Assistant capabilities
* [Database] Removed the use of `advocate` for the Jira data sync so that a connection can be made to the local network.
* [Database] Replace LangChain with pydantic-ai for the AI field and the AI prompt node
* [Core] Use Postgres EXPLAIN-based approximate count for audit log pagination to avoid expensive COUNT(*) on large tables.

### Breaking API changes
* [Integration] Instance SMTP configuration is used by default to send e-mails with the `Send email` action. Set `BASEROW_INTEGRATION_ALLOW_SMTP_SERVICE_TO_USE_INSTANCE_SETTINGS=false` env var to disable this behaviour. [#4999](https://github.com/baserow/baserow/issues/4999)


## Released 2.1.6

### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "bug",
"message": "Forbid wildcard addresses in Postgres data sync",
"issue_origin": null,
"issue_number": null,
"domain": "database",
"bullet_points": [],
"created_at": "2026-04-07"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "feature",
"message": "Add instace wide data scanner.",
"message": "Add instance wide data scanner.",
"issue_origin": "github",
"issue_number": null,
"domain": "database",
Expand Down
4 changes: 4 additions & 0 deletions changelog/releases.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"releases": [
{
"name": "2.2.0",
"created_at": "2026-04-08"
},
{
"name": "2.1.6",
"created_at": "2026-03-13"
Expand Down
Loading
Loading