DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 5153joZg1692512 Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 5153joZg1692512 Authentication-Results: delorie.com; dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=D97ik7w8 X-Recipient: archive-cygwin AT delorie DOT com DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5171B3858428 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com; s=default; t=1738727149; bh=oLW3HqA8L3MMi55rP4fbVi1Xiv5b4NU864fcsGDjnc8=; h=References:In-Reply-To:Date:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=D97ik7w8FTTscGtPvIepdu4+UUZx456gsPj9JF6mMVD91kwJs3QlebJOVWdOkm1XB lAaJA8PnINV1tvAEPTziepXIJEvIZGdaX4LcJsdHJ3d64lL913t+r9ww0+HILcX5Z1 /ZTil8uoZ22xjNTfZIuomY5G4L65zrUoW0sOTtJo= X-Original-To: cygwin AT cygwin DOT com Delivered-To: cygwin AT cygwin DOT com DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 493B83858401 ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 493B83858401 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1738727122; cv=none; b=U6KxKwYW11whDurS7KvGKXAJpJSIcRIIhDmQgS/+HIRMZf1zHXMOCRszM4i9eXiVYaTDIJkPsAvVUDO+mKZFxGcsG6Z0kU/PgkIN2YTC+mp39m2AtiP+JoBfkopyqpm04qBEXH8drtXhCIHqGL5YuQG2YZbegnBrWxDfGyb0vbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1738727122; c=relaxed/simple; bh=DPn8Iq1QmISiQF7dg4bAECNy7UhpvSsJDM4qGnFcIuU=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=ae7mH/66UxekA4BQ1dcbabuktb9HZlwnRoXhzHfunhLIZP0D7ItT1F+pnicaXfsjiPvU9zYbMo8J34fKwq4exuHzQeCC/xhhp06OtgVgQOYRUN9BxQrChv3M6lxvt/bezH/gInuz527wwLKQESGfFQM0UMu6yn/eM67a5QzFidM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 493B83858401 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738727121; x=1739331921; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/iK7Mcv4fqo7xUXwV25OINwcRJXFpXjbRiThD1J5FKc=; b=nBvPV5pdJEC8u1z1jIC/v2zbQZL21q50q9l56uoXy2d6jY8Q3pk2DXATlzlFM0WcA9 3Q5z2+aX7/mqUkk2paILadIn8cQF0o5l6Gw+g4N2NiGRROMfWPzV8whI1rafzKy1JARF o9I4pnOR52oUvqpIq0XkjZYC6OwDNiOsNWdk2IOpMG8Yh84Zqi0RBhFJ2XMjWwVjDW9x waDGq9jZm9HN7dQ+cR4oLN4bgjiUGunkqAQr8c3tUJNwVH0ApeY/5xGA69L2qE8Q9iDs 4S2TZNA9OluU8qpw8dmUIl9OpCCRwwN84ykqdt1MJFrAZNzRDpF+3C6BTl+NjbazTfI9 em2A== X-Gm-Message-State: AOJu0Yyh4c6CVGTWxF56zL0dsnDyZvNLvN06qg27h/4qDeIDHERmSOUP rXMbxbFJBge01ASx3/YkhDVoMNDJxKFs+cxz0voUcpjgukhEcSiSlwz7gzxIKoRrTBFxvulPuqI Y/UjLGQafTLODpRSexFiiEe+qAVeDLunenR3RpvQnhekh4WBBD1Q= X-Gm-Gg: ASbGncv4WRH7OlNaHQ/tfV2IBULCIYhAD8uVAEigPB0oR4Lhu6PcHXEns1680BnGAmA 5YjBNOOnh8quCWYFVvmQlVOEv5skW++WEuyD4o2KF/uM3Q4Myb4Q55HE5wX+rl0hWgqE1QQ== X-Google-Smtp-Source: AGHT+IE+HsUiaqDER1fjRD8yEJe/29mzYpdVBvqRva0V9CfX2yT2o1HTjeBkeTbDL/rep2iSHbN6AmSgzur3KBiyTqI= X-Received: by 2002:a05:6870:ec8a:b0:29e:290f:7aea with SMTP id 586e51a60fabf-2b8051a3215mr1021996fac.34.1738727121127; Tue, 04 Feb 2025 19:45:21 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 5 Feb 2025 11:45:10 +0800 X-Gm-Features: AWEUYZnaUuPoMgVrUEXVSjGa54NXtCFvs3PhdT1YCZAVUFshKBAatgoLDN0uOa8 Message-ID: Subject: Re: Potential Argument Injection Issue in Cygwin's Command Line Handling To: cygwin AT cygwin DOT com X-BeenThere: cygwin AT cygwin DOT com X-Mailman-Version: 2.1.30 List-Id: General Cygwin discussions and problem reports List-Archive: List-Post: List-Help: List-Subscribe: , From: Splitline Ng via Cygwin Reply-To: Splitline Ng Content-Type: text/plain; charset="utf-8" Sender: "Cygwin" Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 5153joZg1692512 Hi Marco, > $ python3.12 > Python 3.12.8 (main, Jan 31 2025, 21:29:51) [GCC 12.4.0] on cygwin > Type "help", "copyright", "credits" or "license" for more information. > import subprocess > subprocess.run(['./test.exe', '"', " a b c"]) > argv[0] = ./test > argv[1] = " > argv[2] = a b c > CompletedProcess(args=['./test.exe', '"', ' a b c'], returncode=0) > > it seems correct to me for a Cygwin Python This behavior appears correct for Cygwin Python because it assumes it is running on a POSIX system. As a result, it uses Cygwin's simulated `execve` system call rather than Windows' command-line parsing mechanism and the parsing mechanism within Cygwin itself is consistent so everything goes fine here. To be more specific, the issue happens when a program thinks it is still on Windows, so it uses Microsoft C startup convention to escape and pass command line string and spawn that executable with CreateProcess API. But it turns out Cygwin C startup function doesn't fully follow that convention. > PS: Windows is not very consistent on quoting behaviour, e.g. > https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md I think we should distinguish between shell parsing and command-line parsing -- command-line parsing is all done by the executable itself instead of the shell (powershell, cmd, bash etc.) On Windows, arguments are parsed by the executable itself rather than the shell. This means the shell does not pass an argv[] array directly to the executable but instead sends the full command line string. Here is a good article about this https://daviddeley.com/autohotkey/parameters/parameters.htm#WIN Regards, splitline On Tue, Feb 4, 2025 at 2:15 PM Splitline Huang wrote: > > Hello Cygwin team, > > I am splitline from DEVCORE research team. I recently have observed an inconsistency > in how Cygwin handles command-line parsing compared to Microsoft’s implementation. > > > According to Microsoft’s documentation [1], the \" sequence should always be > interpreted as a literal double quote ("): > > A double quote mark preceded by a backslash (\") is interpreted as a literal > > double quote mark ("). > > However, in Cygwin, the same sequence treats the backslash as a literal character > and starts quote mode instead. > > [1] https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments > > This inconsistency can cause unexpected behavior when passing executable arguments > via the command line (as opposed to Cygwin’s `execve` method), potentially leading > to argument injection vulnerabilities. > > > Below is my testing process using the Python from Python.org (not the Cygwin version): > > > splitline AT SPLITLINE0D06 ~ > > $ which gcc > > /usr/bin/gcc > > splitline AT SPLITLINE0D06 ~ > > $ cat test.c > > #include > > > int main(int argc, char* argv[], char* envp[]) { > > for (int i = 0; i < argc; ++i) > > printf("argv[%d] = %s\n", i, argv[i]); > > } > > splitline AT SPLITLINE0D06 ~ > > $ gcc test.c -o test.exe > > splitline AT SPLITLINE0D06 ~ > > $ which python > > /cygdrive/c/Python313/python > > splitline AT SPLITLINE0D06 ~ > > $ python > > Python 3.13.1 (tags/v3.13.1:0671451, Dec 3 2024, 19:06:28) [MSC v.1942 > > 64 bit (AMD64)] on win32 > > Type "help", "copyright", "credits" or "license" for more information. > > >>> import subprocess > > >>> subprocess.run(['./test.exe', '"', " a b c"]) # should be only 2 args > > argv[0] = ./test > > argv[1] = \ > > argv[2] = a > > argv[3] = b > > argv[4] = c > > CompletedProcess(args=['./test.exe', '"', ' a b c'], returncode=0) > > >>> > > > > As we can see, it should originally be only 2 arguments: ["] and [ a b c]. However, > the command line is parsed into 4 different arguments. > > Note: With that Python code, the spawned command line is: ./test.exe \" " a b c" > > Please let me know if you have any questions, thanks! > > Best regards, > splitline > DEVCORE > -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple