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@delorie.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@cygwin.com
Delivered-To: cygwin@cygwin.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: <CAM2z_YX8cbwea+he+83924SpZAdofp-srLk3Mzof2U4viXgctQ@mail.gmail.com>
In-Reply-To: <CAM2z_YX8cbwea+he+83924SpZAdofp-srLk3Mzof2U4viXgctQ@mail.gmail.com>
Date: Wed, 5 Feb 2025 11:45:10 +0800
X-Gm-Features: AWEUYZnaUuPoMgVrUEXVSjGa54NXtCFvs3PhdT1YCZAVUFshKBAatgoLDN0uOa8
Message-ID: <CAM2z_YVYuoq28ZzmZn1RTWdRYLNpGMgjBzRQnKdZ0bb4yTmv=w@mail.gmail.com>
Subject: Re: Potential Argument Injection Issue in Cygwin's Command Line
 Handling
To: cygwin@cygwin.com
X-BeenThere: cygwin@cygwin.com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin@cygwin.com>
List-Help: <mailto:cygwin-request@cygwin.com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
 <mailto:cygwin-request@cygwin.com?subject=subscribe>
From: Splitline Ng via Cygwin <cygwin@cygwin.com>
Reply-To: Splitline Ng <splitline@devco.re>
Content-Type: text/plain; charset="utf-8"
Sender: "Cygwin" <cygwin-bounces~archive-cygwin=delorie.com@cygwin.com>
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 <splitline@devco.re> 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@SPLITLINE0D06 ~
>
> $ which gcc
>
> /usr/bin/gcc
>
> splitline@SPLITLINE0D06 ~
>
> $ cat test.c
>
> #include <stdio.h>
>
>
> int main(int argc, char* argv[], char* envp[]) {
>
>     for (int i = 0; i < argc; ++i)
>
>         printf("argv[%d] = %s\n", i, argv[i]);
>
> }
>
> splitline@SPLITLINE0D06 ~
>
> $ gcc test.c -o test.exe
>
> splitline@SPLITLINE0D06 ~
>
> $ which python
>
> /cygdrive/c/Python313/python
>
> splitline@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

