The Secure Copy Protocol (SCP) is a network protocol for securely transferring files between a local computer and a remote host, or between two remote hosts, by leveraging the Secure Shell (SSH) protocol for encryption, authentication, and integrity protection.[1][2] Developed as a secure counterpart to the insecure Remote Copy Protocol (RCP) from the 1980s, SCP emerged in the mid-1990s alongside the initial SSH implementations to address vulnerabilities in unencrypted file transfers over networks.[3][4]SCP operates by establishing an SSH connection and executing commands on the remote system to push or pull files, supporting both single files and recursive directory copies while preserving attributes like permissions and timestamps.[5] Unlike more advanced protocols, it lacks interactive features such as directorybrowsing or file deletion, focusing solely on copy operations for simplicity and efficiency in non-interactive environments.[6][7]The protocol is implemented primarily through the scp command-line utility, which is standard in Unix-like operating systems and available via OpenSSH, the most widely used SSH suite.[8] However, since OpenSSH version 9.0 released in April 2022, the scp tool defaults to the more feature-rich SSH File Transfer Protocol (SFTP) for transfers, rendering the original SCP protocol legacy and accessible only via the -O flag for compatibility with older systems.[9] This shift reflects SCP's limitations, including poor handling of wildcards, progress reporting issues, and reduced extensibility compared to SFTP, prompting recommendations to migrate to modern alternatives for robust secure file handling.[10][11]
Introduction
Definition and Purpose
The Secure Copy Protocol (SCP) is a network protocol designed for securely transferring files between a local host and a remote host, or between two remote hosts, by leveraging the Secure Shell (SSH) protocol for authentication and data protection.[2] It operates over TCP port 22, functioning at the session layer of the OSI model to establish secure sessions for file operations.[12]SCP's primary purposes include enabling the secure copying of individual files, entire directories, and recursive structures while preserving key file attributes such as permissions, modification times, and access times whenever feasible.[4] This makes it suitable for administrative tasks, backups, and deployments in networked environments where data integrity and confidentiality are essential, without requiring additional file transfer services.[2]At its core, SCP relies on SSH as the underlying transport mechanism, utilizing SSH's encryption algorithms—such as AES for symmetric key cryptography—and authentication methods, including public-key cryptography or password-based verification, to ensure end-to-end security during transfers.[13] This integration provides a straightforward, encrypted alternative to unsecure protocols like FTP, focusing on reliable file replication without exposing data in transit.[2]
Historical Development
The Secure Copy Protocol (SCP) originated as a secure alternative to the earlier Remote Copy Protocol (RCP), which was introduced in 1982 by the Computer Systems Research Group at the University of California, Berkeley, as part of the Berkeley r-commands suite for Unix systems. RCP enabled file transfers between Unix hosts but lacked encryption, relying on trusted host authentication that exposed it to eavesdropping and spoofing risks.[3][14]In response to growing security concerns, particularly after network attacks highlighted the vulnerabilities of tools like RCP, Finnish researcher Tatu Ylönen developed SCP in 1995 as an integral component of the initial Secure Shell (SSH) protocol version 1.0. This integration tunneled RCP-like file transfers over SSH's encrypted channel, providing confidentiality, integrity, and authentication without requiring a separate protocol. Ylönen's implementation replaced insecure utilities such as rcp, rsh, and rlogin, marking SCP's debut in the free SSH 1.2.12 release, the last version licensed permissively enough for broad reuse.[15][16]SCP gained widespread standardization following the launch of OpenSSH in 1999, an open-source reimplementation of SSH initiated by the OpenBSD project to ensure free availability and ongoing development. OpenSSH's portable version quickly extended SCP support to Linux and other Unix-like systems, embedding it in core utilities and facilitating seamless adoption across diverse environments. By the late 1990s, major Linux distributions, including early versions of Debian and Red Hat, incorporated OpenSSH packages containing SCP, solidifying its role in enterprise and academic networks for secure file management.[16][17]Despite the emergence of the SSH File Transfer Protocol (SFTP) in the late 1990s as part of SSH version 2—offering more robust features like directory listings and resumable transfers—SCP persisted into the 2000s due to its straightforward syntax and compatibility with legacy scripts. Its simplicity appealed to users prioritizing quick, command-line-based transfers over SFTP's fuller filesystem interaction. However, in April 2019 with OpenSSH 8.0, developers declared the legacy SCP protocol outdated and inflexible, recommending SFTP or rsync for future use amid identified security limitations. The scp command continued to use the legacy SCP protocol until OpenSSH 9.0 released in April 2022, after which it defaults to the SFTP protocol, with legacy SCP mode accessible only via the -O flag for compatibility.[18][9][14]
Protocol Mechanics
Core Functionality
The Secure Copy Protocol (SCP) establishes a secure file transfer by leveraging the Secure Shell (SSH) protocol to create an encrypted channel between client and server hosts. The client initiates the process by connecting to the remote host via SSH and remotely executing the SCP program with specific flags, such as -f for source mode (where the remote acts as the data provider) or -t for sink mode (where the remote acts as the data receiver). This execution sets up a unidirectional communication pipe over the single SSH channel, through which the two SCP instances exchange commands and data using a simple, text-based protocol derived from the older remote copy (RCP) mechanism. Authentication occurs entirely through SSH mechanisms, such as public-key or password-based methods, ensuring the transfer's integrity and confidentiality without additional protocol-level steps.[19]In sink mode, the local client pushes files to the remote server, acting as the source of data. The client sends commands to the remote SCP instance, which responds with acknowledgments (e.g., a null byte 0x00 for success, 0x01 for error, or 0x02 for fatal error). For each file, the client issues a C command formatted as C<mode> <size> <filename>\n, where <mode> is the octal permission string (e.g., 0644), <size> is the file length in bytes, and <filename> is the target path; binary file data follows immediately until the specified size is transferred, after which the remote acknowledges and sets the file attributes. Directories are handled with a D command like D<mode> <size> <dirname>\n (size typically 0 for directories), creating the structure recursively if the -r flag is enabled, followed by an E\n command to exit the directory. Timestamps and access times (to second precision) are preserved via a preceding T command, such as T<mtime> 0 <atime> 0\n where <mtime> and <atime> are Unix timestamps in seconds, ensuring metadata integrity during the push operation. Ownership is not directly transferred in the protocol but relies on the remote user's privileges via SSH.[19]Conversely, in source mode, the remote server pulls files to the local client by the client requesting data from the remote SCP instance. The flow mirrors sink mode but reverses roles: the remote sends C, D, or T commands over the SSH pipe, with the client consuming and applying them locally. File listing occurs implicitly through recursive traversal if directories are involved, where the remote enumerates contents and streams metadata commands before data. All data streaming happens in buffered chunks over the SSH channel's stdin/stdout, typically in 16 KB blocks for efficiency, with the protocol ensuring atomic writes to avoid partial transfers. The process concludes with an E\n command from the sender and a final acknowledgment, closing the channel. This design maintains a lightweight, single-channel operation, prioritizing simplicity over advanced features like resumability.[19]
Transfer Modes
The Secure Copy Protocol (SCP) primarily operates through two fundamental transfer modes: local-to-remote and remote-to-local. In local-to-remote transfers, files are copied from the local host to a remote host over a direct SSH connection, ensuring encrypted transmission of data. Similarly, remote-to-local transfers pull files from a remote host to the local system using the same secure SSH channel. These modes leverage SSH for authentication and encryption, providing a straightforward mechanism for unidirectional file movement between endpoints.[20]For scenarios involving two remote hosts, SCP supports a remote-to-remote transfer mode, which by default attempts a direct connection. This involves the local client initiating an SSH session to the source host and executing an SCP command there to forward the file directly to the destination host, provided the source has SSH access to the destination. This approach minimizes intermediary bandwidth usage but requires network-level connectivity and authentication between the remote hosts. If direct transfer is not feasible—such as when the source cannot reach the destination—an alternative mode routes data through the local host as an intermediate proxy, using separate SSH connections to read from the source and write to the destination, without establishing a direct source-destination link.[20][21]SCP exhibits key limitations in its transfer capabilities, notably the absence of native support for resuming interrupted transfers; any disruption requires restarting the entire operation from the beginning, potentially inefficient for large files. Furthermore, the protocol is inherently single-threaded, processing files sequentially to balance efficiency with the overhead of SSH encryption and authentication, rather than employing parallel streams for concurrent transfers.[22][23]A practical example of the proxy-based remote-to-remote mode occurs when copying files from host A to host C using host B as the intermediary: a user on host B executes the command to fetch data from A via SSH and relay it to C, enabling transfers in environments lacking direct inter-host connectivity.[20]
Implementation Challenges
One significant implementation challenge for the Secure Copy Protocol (SCP) arises from "talkative" shell profiles on the remote host, such as .bashrc or .bash_profile, which generate output even in non-interactive sessions initiated by SCP over SSH.[24] This output, from commands like echo statements, aliases, or message-of-the-day displays, pollutes the standard input/output streams that SCP uses to negotiate and transfer files, leading to protocol parsing failures and transfer errors such as "Write failed flushing stdout buffer" or unexpected exit statuses.[24]Bash, the default shell in many Unix-like systems, sources these profiles during non-interactive login shells invoked by SSH for SCP, exacerbating the issue unless explicitly conditioned to remain silent.[24]Path resolution problems further complicate SCP deployments in non-interactive sessions, where relative paths, tilde expansions (~ for home directories), or glob patterns may resolve incorrectly due to the remote shell's limited environment setup.[25] In legacy SCP mode, which relies on the remote shell to execute commands like file listings or copies, an uninitialized working directory or unset environment variables (e.g., [HOME](/page/Home) or PATH) can direct operations to unintended locations, such as the root directory instead of the user's home, resulting in "No such file or directory" errors or silent failures.[25] These issues stem from the protocol's dependence on the remote shell's interpretation of paths without a full interactive context, making consistent behavior across diverse environments challenging.SCP also depends heavily on a clean SSH environment for reliable operation; verbose logging enabled in sshd_config or non-standard shells can break protocol parsing by introducing extraneous data or incompatible syntax.[26] For example, if a user's default shell is C-shell (csh) or tcsh rather than a POSIX-compliant Bourne shell (sh), the remote commands constructed by SCP—such as "scp -f filename"—may fail due to syntax mismatches, like unhandled semicolons or variable expansions, causing connection closures or malformed responses.[27] Non-standard shells often source their own profiles (e.g., .cshrc) that produce output or alter execution flow, compounding interference similar to talkative Bash profiles.[28]Common workarounds include modifying shell profiles to detect and suppress output in non-interactive sessions, such as adding if [[ $- != *i* ]]; then return; fi at the top of .bashrc to exit early without executing further commands.[24] For path and environment issues, explicitly sourcing a minimal profile or setting variables like $PATH in a dedicated non-interactive script can ensure proper resolution.[25] Additionally, using the -T option with the underlying ssh command (passed via scp -o RequestTTY=no) disables pseudo-terminal allocation, enforcing a stricter non-interactive mode that avoids profile triggers dependent on terminal presence, though this is supplementary to profile quieting.[29] In cases of non-standard shells, temporarily overriding the user's shell to /bin/sh via SSH configuration or forcing SFTPmode in modern OpenSSH implementations bypasses shell-specific parsing altogether.[26]
Software Implementations
Primary Command-Line Interface
The primary command-line interface for the Secure Copy Protocol is the scp utility, provided as part of the OpenSSH suite and serving as the canonical tool for secure file transfers on Unix-like systems. OpenSSH, originating from the OpenBSD project, first included scp in its portable release in October 1999, enabling widespread adoption across Linux distributions, BSD variants, and other platforms where it has remained a core component ever since.[16] Since OpenSSH version 9.0 (released April 2022), the scp tool defaults to using the SSH File Transfer Protocol (SFTP) for transfers instead of the legacy SCP protocol; the -O option must be used to invoke the original SCP protocol for compatibility.[9] This implementation replaced insecure predecessors like rcp by tunneling file operations over SSH, ensuring encrypted transfers and robust authentication.[4]In practical use, scp is invoked with the basic syntax scp [options] source destination, where the source and destination specify local paths or remote locations in the format [user@]host:path. This straightforward command facilitates copying files or directories between local and remote hosts, or between two remote hosts, while automatically handling the underlying SSH connection for security.[4] Key features enhance its utility: the -r option enables recursive copying of entire directory trees, the -p flag preserves original file modification times, access times, and mode bits, and the -C option activates compression through the SSH protocol to optimize bandwidth usage during transfers.[4]For authentication, scp seamlessly integrates with SSH public-key mechanisms, allowing passwordless operation when keys are set up via tools like ssh-keygen and managed by ssh-agent. It inherits the default configuration from the ssh client, including support for custom ports (-P), identity files (-i), and other SSH options passed via -o, ensuring consistent behavior across OpenSSH tools in diverse network environments.[4]
Syntax and Options
The scp command follows the syntax scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-J destination] [-l limit] [-o ssh_option] [-P port] [-S program] [-X sftp_option] source ... target, where source and target can specify local paths, remote hosts in the format [user@]host:[path], or URI-style scp://[user@]host[:port][/path].[4] Local paths should use absolute or relative specifications to prevent misinterpretation of colons as host delimiters.[4]Key options include -r to recursively copy entire directories, -i identity_file to specify a private key file for authentication, -P [port](/page/Port) to connect to a non-standard SSH port on the remote host, and -l [limit](/page/Limit) to throttlebandwidth usage in kilobits per second.[4] Other notable flags are -p to preserve original file modification times and permissions during transfer, -C to enable compression for faster transfers over slow links, -v for verbose output to aid debugging, and -q for quiet mode that suppresses progress meters and non-error messages.[4] The -O option forces use of the legacy SCP protocol instead of the default SFTP-based method, which may be necessary for compatibility with older servers.[4]For example, to copy a local file to a remote host, use scp localfile user@remotehost:/path/to/destination.[4] To transfer from one remote host to another via the local machine, employ the -3flag: scp -3 user1@host1:/path/to/source user2@host2:/path/to/target.[4] Recursive directory copies require -r, such as scp -r localdir user@remotehost:/path/to/destination.[4]The scp utility exits with status 0 on successful completion and a value greater than 0 if an error occurs, such as connection failures or permission issues.[4] Common errors include "permission denied," typically caused by invalid credentials, insufficient read permissions on the source, or write permissions on the target directory; troubleshooting involves verifying SSH access with ssh first, checking file ownership with ls -l, and using -v for detailed logs.[4] Another frequent issue is "No such file or directory," often due to incorrect paths or unescaped special characters; resolve by quoting paths with spaces and confirming remote paths via SSH.[30]
Third-Party Clients
Several third-party clients implement the Secure Copy Protocol (SCP) outside of the standard OpenSSH distribution, catering to specific platforms, graphical interfaces, or integration needs. These tools provide alternatives for users on Windows or in enterprise environments, often extending SCP functionality with platform-specific features while maintaining compatibility with SSH-based authentication.One prominent example is PSCP, the command-line Secure Copy client included in the PuTTY suite, designed primarily for Windows users. PSCP enables secure file transfers over SSH connections, using syntax closely aligned with the traditional scp command, such as pscp source destination for copying files between local and remote systems. It integrates seamlessly with Pageant, PuTTY's SSH authenticationagent, allowing the use of public key authentication without repeatedly entering passphrases, which enhances usability in automated or multi-session workflows.For graphical user interfaces, WinSCP offers a free, open-source file manager for Windows that supports SCP alongside SFTP, FTP, and other protocols. Its drag-and-drop interface simplifies file transfers, enabling users to visually navigate remote directories and initiate copies without command-line knowledge, while preserving SCP's encryption for secure operations. WinSCP also includes features like synchronization and scripting support, making it suitable for both ad-hoc and batch transfers in professional settings.[31]Beyond desktop clients, SCP is embedded in various enterprise and network management tools for specialized use cases. For instance, Cisco IOS integrates SCP server functionality directly into its operating system, allowing network administrators to securely copy configuration files or firmware images to and from routers and switches using commands like copy scp: flash:. This implementation leverages the device's built-in SSH capabilities, facilitating automated updates in large-scale deployments without requiring external software.[32]On cross-platform fronts, macOS includes SCP support natively through its OpenSSH installation, accessible via the Terminal for Unix-like file transfers. For programmatic use, the Paramiko library in Python provides a pure-Python implementation of SSHv2, including SCP capabilities via extensions like scp.py, enabling scripted secure copies in cross-platform applications without relying on system binaries.[26][33]
Security Considerations
Protection Mechanisms
The Secure Copy Protocol (SCP) relies entirely on the underlying Secure Shell (SSH) protocol for its security protections, without implementing any protocol-specific mechanisms of its own. This integration ensures that file transfers occur over an encrypted channel, safeguarding against unauthorized access and tampering during transit. SCP sessions establish an SSH connection, through which all data is protected using SSH's cryptographic primitives, providing confidentiality, authentication, and integrity as core safeguards.[26]Encryption in SCP is handled by SSH's transport layer, which negotiates symmetric ciphers to protect data in transit from eavesdropping. Common ciphers include AES-128-CTR, a stream cipher mode that encrypts file contents and metadata with a 128-bit key, ensuring that intercepted packets reveal no readable information. Other supported options, such as AES-192-CTR and AES-256-CTR, offer varying key lengths for enhanced security, with selection based on mutual agreement between client and server during connection setup. This cipher-based encryption applies bidirectionally, covering both upload and download operations in SCP.[34][35]Authentication for SCP is managed through SSH's user and host verification processes, preventing unauthorized entities from initiating transfers. It supports public-key methods using algorithms like RSA or Ed25519, where the client proves possession of a private key corresponding to a public key stored on the server, eliminating the need for password entry. Password-based authentication serves as an alternative, transmitting credentials securely over the encrypted channel for server-side verification. Additionally, host-based authentication allows trusted hosts to authenticate users without individual credentials, relying on pre-configured equivalence files like /etc/hosts.equiv. These methods collectively ensure only authorized parties can access remote file systems via SCP.[36]Data integrity in SCP is maintained by SSH's use of message authentication codes (MACs), which detect any modifications to transferred packets. MACs such as HMAC-SHA2-256 compute a hash over the packet data, sequence number, and a shared secret, appending it to each message for server-side validation. This prevents man-in-the-middle alterations, with truncated variants like HMAC-SHA2-256-96 available for efficiency in high-throughput transfers. By inheriting these SSH features, SCP provides comprehensive protections for confidentiality, integrity, and availability without introducing additional layers.[34][37]
Identified Vulnerabilities
The Secure Copy Protocol (SCP) has been subject to several identified vulnerabilities, primarily stemming from its implementation details and historical design choices. One prominent flaw is CVE-2019-6111, discovered in OpenSSH 7.9 and affecting versions up to that release, which enables a malicious SCP server or man-in-the-middle attacker to overwrite arbitrary files on the client side through symlink attacks.[38] This vulnerability arises because the SCP client, derived from the 1983 Remote Copy Protocol (RCP), performs insufficient validation of filenames and paths provided by the server during recursive operations, allowing attackers to manipulate symlinks and redirect content to sensitive locations such as .ssh/authorized_keys.[38] The issue was mitigated in OpenSSH 8.0 by adding client-side filename checks to ensure they match the command-line request.[18]SCP's heritage from the RCP protocol, originally implemented in 1983, introduces legacy flaws related to poor permission checking on the client side, which can enable data leakage or unauthorized access if the remote server is misconfigured or compromised.[38] In this design, the server dictates the files and directories sent to the client without robust verification, potentially exposing sensitive data during transfers over untrusted networks.[39] These inherited weaknesses highlight the protocol's outdated trust model, where the client blindly applies server-specified permissions.More recent vulnerabilities include CVE-2024-20262 in Cisco IOS XR Software, which allows an authenticated local attacker to create or overwrite files in the FTP serverroot directory via crafted SCP or SFTP requests due to inadequate path validation.[40] This flaw affects multiple releases of Cisco IOS XR, enabling privilege escalation to root if exploited, and is limited to scenarios where the attacker invokes SCP or SFTP from the device's CLI.[41] Similarly, CVE-2025-53868 impacts F5 BIG-IP systems in appliance mode, where improper neutralization of special elements in SCP and SFTP commands leads to OS command injection (CWE-78), potentially granting privileged access to attackers.[42] This vulnerability affects BIG-IP versions 17.1.0 through 17.1.2 and 17.5.0 across all modules, allowing execution of arbitrary commands with elevated privileges.[42]Beyond specific CVEs, SCP exhibits general security issues, such as the lack of native support for TLS/SSL encryption, relying instead solely on the underlying SSH transport layer for confidentiality. The protocol's use of a single stream for both control and data transfers makes it particularly vulnerable to denial-of-service (DoS) attacks, especially during large file operations that can exhaust resources.[18] For scenarios requiring interactive file management or better permission handling, SFTP is recommended as a more secure and flexible alternative to SCP.[18]To mitigate these vulnerabilities, users should update to the latest versions of OpenSSH, such as 10.2 (released October 2025) or later, which include fixes for historical SCP flaws and enhanced security features.[43] Enabling strict host key checking with the StrictHostKeyChecking=yes option in SSH configurations helps prevent man-in-the-middle attacks by verifying host identities during connections. Additionally, avoid using SCP with untrusted remote sources, and prefer SFTP or rsync over SSH for transfers involving potentially adversarial endpoints.[18]