Database links and linked servers store a credential for one database inside another, so a foothold in the least important database can become a session in the most important one. SQL Server linked servers, Oracle database links and PostgreSQL foreign data wrappers exist for good reasons: reporting, migrations, replication and cross-system queries. Each one is a non-human identity with a remote login, a password or a delegated identity, and a trust path that rarely appears on any diagram. This guide explains how each platform stores and maps these credentials, how to find every link and the path it creates, and how to replace fixed passwords with narrower designs. It is for database administrators, identity and NHI teams, and security engineers mapping lateral movement risk. Platforms are listed alphabetically by vendor.
Key takeaways
- A link is a stored credential. Fixed-login linked servers, fixed-user Oracle links and PostgreSQL user mappings with passwords all keep a remote secret in the local database.
- The dangerous setting is the "everyone" mapping. A SQL Server mapping with
@locallogin = NULL, an Oracle PUBLIC fixed-user link or a PostgreSQL PUBLIC user mapping gives every local user the remote account's rights. - Links chain. Database A links to B, which links to C, so the effective reach of a low-privilege login can be several hops away. Map paths, not just links.
- Prefer the caller's own identity. Self-mapping with Kerberos delegation, Oracle connected-user or CURRENT_USER links and PostgreSQL GSSAPI or SCRAM pass-through avoid a shared stored password.
- Inventory links as NHIs. Each needs an owner, a purpose, a remote account with least privilege and a review date.
How each platform stores the remote identity
| Platform | Object | Credential options | "Everyone" form | Privilege to create |
|---|---|---|---|---|
| Microsoft SQL Server | Linked server (sp_addlinkedserver) plus login mappings (sp_addlinkedsrvlogin) | @useself = true (caller's own credentials) or @useself = false with @rmtuser and @rmtpassword | Mapping with @locallogin = NULL applies to all local logins | ALTER ANY LOGIN for login mappings |
| Oracle Database | Database link (CREATE DATABASE LINK) | Fixed-user (CONNECT TO user IDENTIFIED BY), connected-user (no CONNECT TO), current-user (CONNECT TO CURRENT_USER), or a credential object via CONNECT WITH | CREATE PUBLIC DATABASE LINK makes a link visible to all users | CREATE DATABASE LINK or CREATE PUBLIC DATABASE LINK |
| PostgreSQL | Foreign server plus user mapping (postgres_fdw) | User mapping with user and password, client certificates (sslcert, sslkey), GSSAPI delegated credentials or use_scram_passthrough | A user mapping for PUBLIC applies to any role without its own mapping | Superuser for certificate options and for password_required 'false' |
Microsoft SQL Server
- Default mapping: Microsoft's documentation states that
sp_addlinkedservercreates a default mapping for all local logins, equivalent to@useself = true. Each caller then connects with their own credentials, which is the safer starting point. - Fixed remote login:
@useself = falsewith a remote user and password stores that credential on the server. With@locallogin = NULLit applies to every local login. Explicit per-login mappings take precedence over the global one. - Microsoft's guidance: the sp_addlinkedserver documentation notes that the default self-mapping applies to all local logins and that, for non-SQL Server providers, SQL Server authenticated logins might reach the provider under the SQL Server service account; it suggests administrators consider removing the global mapping with
sp_droplinkedsrvlogin. For Windows identities, Microsoft documents Active Directory pass-through with full delegation and, from SQL Server 2017 CU17, with constrained delegation; use one of these documented delegation modes for multi-hop access. - Remote permissions are remote: once connected, object permissions are decided by the remote server for the mapped login, not by the local server.
- Encryption: with MSOLEDBSQL 19 and SQL Server 2025, Microsoft documents
Encrypt=Mandatoryas the default and advises againstTrustServerCertificate=Yesin production. Use the MSOLEDBSQL provider rather than the legacy SQLNCLI or SQLOLEDB providers. - Managed Instance: Azure SQL Managed Instance supports managed identity and Microsoft Entra pass-through for linked servers, which removes the stored password.
Deeper SQL Server hardening is in the SQL Server Security Guide.
Oracle Database
- Fixed-user links connect as the named account whoever uses the link. As a PUBLIC link, every local user gets that remote account's privileges; Oracle's documentation states that a PUBLIC link is visible to all users, so choose its identity with care (our recommendation).
- Connected-user links use the local user's own credentials on the remote side, so the user must exist there.
- CURRENT_USER links use the current user in scope: inside a definer-rights stored object that is the object's owner, inside an invoker-rights unit it is the caller. The user must be a global user with an account on the remote database. Review definer-rights code that uses these links, because callers inherit the owner's remote reach.
- Credential objects:
CONNECT WITHuses a credential managed byDBMS_CREDENTIAL; another user can use it only if grantedEXECUTE. This separates the password from the link definition and lets you rotate it in one place. - Shared links require an authentication clause for the users allowed to use the shared connection.
See the Oracle Database Security Guide for wider Oracle hardening.
PostgreSQL
- User mappings hold the secret:
user,passwordandsslpasswordcannot be server options inpostgres_fdw; they live in a user mapping or a service file. - password_required: only a superuser can set
password_required 'false'. The PostgreSQL documentation warns this can let a mapped user connect as a superuser to the mapped database, and says not to set it for thepublicrole. - SCRAM pass-through:
use_scram_passthroughavoids storing plain-text passwords in the catalogue, provided the remote server requestsscram-sha-256, both servers hold identical SCRAM secrets for the user, and the incoming client connection also uses SCRAM. The option is documented from PostgreSQL 18; confirm it in the documentation for your release.
See the PostgreSQL Security Guide for role and authentication hardening.
Finding every link and the path it creates
Discovery has two parts: list the link objects on every instance, then join them into a graph.
| Platform | Where to look | What to record |
|---|---|---|
| Microsoft SQL Server | sys.servers (linked server definitions), sys.linked_logins (login mappings: server_id, local_principal_id, where 0 means all logins, uses_self_credential, remote_name, modify_date; the password is not exposed), sp_linkedservers | Remote data source, provider, whether each mapping uses self credentials, the local login (or all logins) and the remote login name. From SQL Server 2022, reading sys.linked_logins needs VIEW SERVER SECURITY STATE. |
| Oracle Database | DBA_DB_LINKS (all links: OWNER, DB_LINK, USERNAME, HOST, CREATED, VALID), DBA_CREDENTIALS where credential objects are used | Owner (PUBLIC or schema), link name, remote user name, host or connect string, whether the link is valid |
| PostgreSQL | pg_foreign_server, pg_user_mappings (srvname, umuser, which is 0 for a PUBLIC mapping, usename, umoptions) | Foreign server, mapped local role (including PUBLIC), remote user, whether a password or certificate is set. umoptions reads as NULL unless you are a superuser or meet the documented owner conditions, so run discovery as a suitably privileged role. |
Then build the graph:
- Collect from every instance, including development, reporting and migration servers that are often forgotten. The CMDB rarely records links; see the Asset Inventory and CMDB Security Guide for where to store the result.
- Resolve the remote end: map the remote host and login to an instance and a role, and record that role's privileges on the target.
- Draw edges: source instance and who can use the link (all logins, a named login, PUBLIC) to target instance and remote role.
- Walk paths: find every chain from low-trust instances (development, reporting, internet-facing applications) to high-trust ones (finance, identity stores, production master data). A three-hop path from a reporting server to a finance database is the finding that matters.
- Rank: fixed credential plus all-users mapping plus privileged remote role is the top priority.
Risk patterns and the safer alternative
| Pattern | Why it is risky | Safer design |
|---|---|---|
| All-logins mapping to a fixed remote login | Every local login, including application and reporting accounts, acts as that remote login | Map named logins only, or use self-mapping with delegation |
| Remote login is sysadmin, DBA or superuser | One link equals administrative control of the target | Dedicated remote account with only the objects the job needs |
| Oracle PUBLIC fixed-user link | Every schema, including low-privilege ones, uses the remote account | Private link owned by the schema that needs it, or a CURRENT_USER link |
PostgreSQL PUBLIC mapping or password_required 'false' | Any role can connect, potentially with the server's own trust | Per-role mappings, password or SCRAM pass-through, never on PUBLIC |
| Links left from a finished migration | Unused credential with live access | Remove at project close and record it in the change |
| Development instance linked to production | Development security is lower, so production inherits it | No links from lower to higher environments; use data pipelines with their own identity |
Remediation roadmap
- Discover (weeks 1 to 3): run the queries above on every instance and build the graph. Read-only, no risk.
- Assign owners (weeks 2 to 4): each link gets an application owner and a stated purpose. Links with no owner after four weeks go on the removal list (our recommendation).
- Remove unused links (weeks 4 to 8): enable auditing of link use first, wait a full business cycle including month end, then drop links with no use. Keep the definition script, minus the password, for rollback.
- Narrow mappings (weeks 6 to 12): replace all-logins and PUBLIC mappings with named mappings; replace privileged remote logins with purpose-built accounts. Test each change in a lower environment with the real jobs.
- Remove stored passwords (ongoing): move to delegation, managed identity, CURRENT_USER or SCRAM pass-through where the platform supports it; otherwise rotate remote passwords on your standard schedule and keep them in a credential object or secrets manager. See the Database Credential and Access Security Guide.
- Prevent new risky links: restrict who can create links (
ALTER ANY LOGIN,CREATE PUBLIC DATABASE LINK, superuser) and require a change record for each new link. See Database Change and Schema Migration Security.
Detection and measurement
- New link or mapping created: alert on
sp_addlinkedserver,sp_addlinkedsrvlogin,CREATE DATABASE LINK,CREATE USER MAPPINGandALTER USER MAPPINGoutside approved changes. - Remote logins arriving from database servers: on the target, sessions whose client host is another database server and whose login is used by a link. Unusual source servers or times are worth investigating.
- Link use by unexpected local users: where auditing captures distributed queries, a login that has never used the link before.
- Privileged commands over a link: administrative statements executed through a linked session.
The Database Audit Log Detection Guide covers how to collect these events per platform. Metrics to track:
- Total links, and the number with fixed credentials.
- Number of all-logins or PUBLIC mappings (target: zero).
- Number of links whose remote account has administrative rights (target: zero).
- Number of paths from lower environments to production.
- Percentage of links with a named owner and review date.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | ATT&CK technique addressed |
|---|---|---|---|
| Inventory of links and owners | CM-8, CA-3 | PR.AA-01 | T1078 Valid Accounts |
| Least privilege remote accounts and mappings | AC-6, AC-6(5) | PR.AA-05 | T1078.003 Local Accounts |
| Stored credential handling and rotation | IA-5 | PR.AA-01 | T1555 Credentials from Password Stores |
| Restricting trust paths between environments | AC-4, CA-3 | PR.AA-05 | T1021 Remote Services |
| Detection of link creation and use | AU-2, SI-4 | DE.CM-09 | T1505.001 SQL Stored Procedures |
Common failure patterns
- Linked server created in a hurry with the "sa" login for every local user, and never revisited.
- Inventory by instance, not by path: each server looks acceptable alone while the chain reaches production.
- Passwords in saved scripts: the link definition script with the remote password sits in a repository or share.
- Definer-rights code using CURRENT_USER links without review, so callers inherit the owner's remote access.
- Migration links never removed after cut-over, with the remote account still enabled.
- Certificate validation switched off on the link to "make it work", exposing the remote credential in transit.
Practitioner checklist
- List every linked server, database link and foreign server on every instance, including non-production.
- Join links into a graph and find paths from lower-trust to higher-trust databases.
- Remove all-logins, PUBLIC and
password_required 'false'mappings. - Replace administrative remote logins with purpose-built least-privilege accounts.
- Prefer self-mapping with delegation, managed identity, CURRENT_USER or SCRAM pass-through over stored passwords.
- Keep remaining passwords in credential objects or a secrets manager and rotate them.
- Restrict who can create links and alert on new links and mappings.
- Give each link an owner, a purpose and a review date, and review quarterly.
Standards and references
- Microsoft Learn: Linked servers (Database Engine)
- Microsoft Learn: sp_addlinkedsrvlogin (Transact-SQL)
- Oracle: CREATE DATABASE LINK, SQL Language Reference
- Oracle: DBA_DB_LINKS, Database Reference
- PostgreSQL: postgres_fdw documentation
- NIST: SP 800-53 Rev. 5 Security and Privacy Controls
Related NHI Mgmt Group resources: Database Security Guide, SQL Server Security Guide, Oracle Database Security Guide, Database Privileged Access Review Template.