[ 
https://issues.apache.org/jira/browse/AVRO-4313?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ismaël Mejía updated AVRO-4313:
-------------------------------
    Description: 
When Avro generates Java classes from a schema, the value of the 
{{javaAnnotation}} schema property is written *as-is* into the generated source 
code. To keep this safe, {{SpecificCompiler}} validates each value with a 
regular expression that is supposed to accept only a Java annotation shape: an 
identifier optionally followed by a parameter list, e.g.

{code:java}
@Deprecated
@SuppressWarnings("unchecked")
{code}

The validation regex was too permissive. The part that matches a quoted string 
(for example {{"unchecked"}}) allowed an *unescaped double-quote inside the 
string body*. As a result, a single "string literal" could run past its 
intended closing quote and absorb whatever followed it, while the value as a 
whole still matched the "valid annotation" shape.

This means a crafted {{javaAnnotation}} value such as:

{code:java}
java.lang.SuppressWarnings("x") static { System.exit(1); } 
@java.lang.SuppressWarnings("y")
{code}

passes validation and is emitted verbatim into the generated class — injecting 
arbitrary declarations and a static initializer that runs when the class is 
loaded.

h3. Impact

Anyone who can influence a schema's {{javaAnnotation}} property can inject 
arbitrary Java into the generated (and subsequently compiled) sources.

h3. Fix

Tighten the string-literal grammar so its body may only contain recognized 
escape sequences ({{\\ \" \n \t \f \b}}) or characters that are not a quote, 
backslash, or line terminator. An unescaped quote now correctly ends the 
literal, so injected trailing tokens no longer match and the value is rejected. 
Line terminators (CR, LF, NEL, LS, PS) are also excluded so a value cannot 
spill onto extra lines. Legitimate annotations 
({{SuppressWarnings("unchecked")}}, {{Deprecated(forRemoval = true, since = 
"forever")}}, and values with escaped quotes) continue to validate. A 
regression test is added.

  was:
The {{javaAnnotation}} validator in {{SpecificCompiler}} uses a regular 
expression (\{{PATTERN_STRING}}) whose string-literal grammar accepts an 
unescaped quote inside the literal body. As a result a single string literal 
can extend past its intended closing quote and absorb arbitrary tokens, so a 
crafted {{javaAnnotation}} value can full-match the {{IDENTIFIER(STRING)}} 
shape while actually containing extra Java declarations. Because the record 
template emits annotation values verbatim, such a value would be written 
directly into the generated specific-record source.

This tightens the string-literal grammar so the body may only contain 
recognized escape sequences or characters that are not a quote, backslash, or 
line terminator. Legitimate annotation values (for example 
{{{}SuppressWarnings("unchecked"){}}}, {{{}Deprecated(forRemoval = true, since 
= "forever"){}}}, and values with escaped quotes) continue to validate. A 
regression test is added.

        Summary: [java] javaAnnotation values can inject arbitrary Java code 
into generated sources  (was: [java] Tighten javaAnnotation string-literal 
validation in SpecificCompiler)

> [java] javaAnnotation values can inject arbitrary Java code into generated 
> sources
> ----------------------------------------------------------------------------------
>
>                 Key: AVRO-4313
>                 URL: https://issues.apache.org/jira/browse/AVRO-4313
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: java
>    Affects Versions: 1.11.5, 1.12.1
>            Reporter: Ismaël Mejía
>            Assignee: Ismaël Mejía
>            Priority: Major
>              Labels: pull-request-available
>             Fix For: 1.13.0, 1.12.2
>
>          Time Spent: 1h
>  Remaining Estimate: 0h
>
> When Avro generates Java classes from a schema, the value of the 
> {{javaAnnotation}} schema property is written *as-is* into the generated 
> source code. To keep this safe, {{SpecificCompiler}} validates each value 
> with a regular expression that is supposed to accept only a Java annotation 
> shape: an identifier optionally followed by a parameter list, e.g.
> {code:java}
> @Deprecated
> @SuppressWarnings("unchecked")
> {code}
> The validation regex was too permissive. The part that matches a quoted 
> string (for example {{"unchecked"}}) allowed an *unescaped double-quote 
> inside the string body*. As a result, a single "string literal" could run 
> past its intended closing quote and absorb whatever followed it, while the 
> value as a whole still matched the "valid annotation" shape.
> This means a crafted {{javaAnnotation}} value such as:
> {code:java}
> java.lang.SuppressWarnings("x") static { System.exit(1); } 
> @java.lang.SuppressWarnings("y")
> {code}
> passes validation and is emitted verbatim into the generated class — 
> injecting arbitrary declarations and a static initializer that runs when the 
> class is loaded.
> h3. Impact
> Anyone who can influence a schema's {{javaAnnotation}} property can inject 
> arbitrary Java into the generated (and subsequently compiled) sources.
> h3. Fix
> Tighten the string-literal grammar so its body may only contain recognized 
> escape sequences ({{\\ \" \n \t \f \b}}) or characters that are not a quote, 
> backslash, or line terminator. An unescaped quote now correctly ends the 
> literal, so injected trailing tokens no longer match and the value is 
> rejected. Line terminators (CR, LF, NEL, LS, PS) are also excluded so a value 
> cannot spill onto extra lines. Legitimate annotations 
> ({{SuppressWarnings("unchecked")}}, {{Deprecated(forRemoval = true, since = 
> "forever")}}, and values with escaped quotes) continue to validate. A 
> regression test is added.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to