On Wed, 2 Sep 2026 19:33:17 GMT, Sean Mullan <[email protected]> wrote:

>> Alternate implementation - this version only contains one argument - the 
>> name of the properties file. If an include statement is needed, it should be 
>> inserted in the properties file and it will always be added as the last line 
>> of the the conf/security/java.security configuration file.. 
>> 
>> See https://github.com/openjdk/jdk/pull/30635 for the other implementation. 
>> 
>> This is a new jlink plugin which allows the user to specify values of 
>> security properties it wants to override in the conf/security/java.security 
>> configuration file in a custom runtime image. This enhancement, along with 
>> https://github.com/openjdk/jdk/pull/29700 allow users to more easily create 
>> runtimes that address the specific security requirements of their 
>> applications.
>> 
>> The command-line syntax takes a file containing properties that the user 
>> wants to override. The file can also contain an include statement which will 
>> be added as the last line of the conf/security/java.security configuration 
>> file.
>> 
>> For example:
>> 
>> jlink --security-properties props.security
>> 
>> where props.security is a file containing one more more properties in the 
>> java.security file syntax.
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> Sean Mullan has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains 43 commits:
> 
>  - Merge
>  - Add test for modular image using customized java.security file.
>    Add other various improvements and tests for different property syntax.
>  - Use Properties API to parse each property.
>    Add method to determine if props file has comments or blank lines.
>    Add method to determine if property is multi-lined value.
>    Store props in Properties object instead of Map.
>  - Add extract method to JModTask.
>  - Revert change made to java.security file.
>  - Support lines of just whitespace.
>  - Support all delimiters ('=', ':', whitespace)
>  - Use ISO_8859_1 to read/write property files.
>    Improve SkippedException message.
>  - Alternate jlink --security-properties implementation. There is no separate
>    option for the include file.
>  - Document that comments in the properties file are ignored.
>  - ... and 33 more: https://git.openjdk.org/jdk/compare/9c6e2f49...55f102ed

Hi @seanjmullan, thank you for the updates, I discovered other potential 
problems with the escaping of user-defined properties.

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SecurityPropertiesPlugin.java
 line 146:

> 144:                 if (propValue != null) {
> 145:                     // override value
> 146:                     lines.add(propName + "=" + propValue);

`propName` and `propValue` raw values are passed unescaped, this will work for 
ISO-8859-1 characters, but will fail for Unicode characters greater than 
`\u00FF`, backward slashes, spaces in keys, and idented or multi-line values.

For example, if the file passed as `--security-properties` contains properties 
with `\` or `\u20AC`, `extraProps` will have them parsed as `` or `€`. When 
writing to the ISO-8859-1 byte array, the backward slash will be stored as a 
single slash (which the `Properties` parser discards) and the Euro sign as a 
question mark.

Perhaps we can use [`Properties.store(OutputStream out, String 
comments)`](https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/Properties.html#store(java.io.OutputStream,java.lang.String))
 in a similar way as you did with `Properties.load()` (one property at a time). 
It handles the escaping properly, the only caveat is it will require removing 
the header date comment and a trailing newline:


jshell -<<'EOF'
Properties test = new Properties();
test.put("aaa", "euro_\u20AC_value");
test.put("abb", "slash_\_value");
test.put("euro_\u20AC_key", "111");
test.put("slash_\_key", "222");
test.put("spaced key", "333");
test.put("zyy", "   indented value");
test.put("zzz", "multi-line\nvalue");
test.list(System.out);

System.out.println("-- showing Properties.store() result --")
ByteArrayOutputStream bao = new ByteArrayOutputStream();
test.store(bao, null);
System.out.println(bao.toString(StandardCharsets.ISO_8859_1));
EOF


Output:


-- listing properties --
aaa=euro_€_value
abb=slash__value
euro_€_key=111
slash__key=222
spaced key=333
zyy=   indented value
zzz=multi-line
value
-- showing Properties.store() result --
#Thu Sep 03 16:07:22 CEST 2026
aaa=euro_\u20AC_value
abb=slash_\_value
euro_\u20AC_key=111
slash_\_key=222
spaced\ key=333
zyy=\   indented value
zzz=multi-line\nvalue



The core escaping logic is in 
[`Properties.saveConvert()`](https://github.com/openjdk/jdk/blob/e9222ab58987711adafd598a01b7ad58ab25f895/src/java.base/share/classes/java/util/Properties.java#L682-L738).
 For the [JDK-8319332: Security properties files 
inclusion](https://bugs.openjdk.org/browse/JDK-8319332) test, we implemented [a 
simplified 
version](https://github.com/openjdk/jdk/blob/e9222ab58987711adafd598a01b7ad58ab25f895/test/jdk/java/security/Security/SecurityPropFile/ExtraFileAndIncludes.java#L475-L495),
 but please note I didn't know about the `Properties::store` method.

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SecurityPropertiesPlugin.java
 line 160:

> 158: 
> 159:         // add user-defined properties at end
> 160:         extraProps.forEach((k, v) -> lines.add(k + "=" + v));

`k` and `v` are not escaped here (more details in previous comment).

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SecurityPropertiesPlugin.java
 line 165:

> 163:         // space character as delimiter
> 164:         if (includeValue != null) {
> 165:             lines.add("include " + includeValue);

`includeValue` is not escaped here (more details in previous comment).

src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties line 
183:

> 181: 
> 182: security-properties.usage=\
> 183: \  --security-properties props=<filename>\n\

It seems 79aa0d7af1264737d1724cee039f4f02315aee70 forgot to remove `props=` 
here.

-------------

PR Review: https://git.openjdk.org/jdk/pull/31884#pullrequestreview-5102092761
PR Review Comment: https://git.openjdk.org/jdk/pull/31884#discussion_r3925409264
PR Review Comment: https://git.openjdk.org/jdk/pull/31884#discussion_r3925410670
PR Review Comment: https://git.openjdk.org/jdk/pull/31884#discussion_r3925411054
PR Review Comment: https://git.openjdk.org/jdk/pull/31884#discussion_r3924696438

Reply via email to