Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secrets with non-printable characters are corrupted on the app side #430

Open
dima-starosud opened this issue Feb 11, 2022 · 0 comments
Open
Labels
type: bug Something isn't working

Comments

@dima-starosud
Copy link

dima-starosud commented Feb 11, 2022

Expected Behavior

All k8s secrets are properly base64-decoded on application side.

Actual Behaviour

Some of the secrets (in particular ZuD1WklPYQCr) are corrupted when received by @Value inside the service.

Steps To Reproduce

  1. Add following k8s secret, note it contains non-printable characters, and on service side it's consumed as byte[]:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-secret
  namespace: default
data:
  MY_SECRET: "ZuD1WklPYQCr"
  1. Use it in the service on application side:
@Singleton
@Slf4j
public class MyService {
    public MyService(
            @Value("${MY_SECRET}") byte[] corrupted
    ) {
        // use one provided by Micronaut
        log.warn("Corrupted: {}", corrupted);
        log.warn("Encoded corrupted: {}", Base64.getEncoder().encodeToString(corrupted));

        // manual decoding
        var expected = Base64.getDecoder().decode("ZuD1WklPYQCr".getBytes());
        log.warn("Expected: {}", expected);
        log.warn("Encoded expected: {}", Base64.getEncoder().encodeToString(expected));
    }
}
  1. Output will be following:
Corrupted: [102, -17, -65, -67, -17, -65, -67, 90, 73, 79, 97, 0, -17, -65, -67]
Encoded corrupted: Zu+/ve+/vVpJT2EA77+9
Expected: [102, -32, -11, 90, 73, 79, 97, 0, -85]
Encoded expected: ZuD1WklPYQCr
  1. So, as one can see bytes were changed during the traveling from k8s to the service.

Details

Tried to investigate a bit, and it looks like Micronaut uses new String(v.getValue()) here in KubernetesUtils.java, instead of passing byte[] as is. And this conversion to String actually changes byte-representation.

Removing this conversion actually fixes the issue, but requires more changes in core/*/AbstractInitializableBeanDefinition.java, where it does applicationContext.resolvePlaceholders(stringValue), which resolves to String, I think here would be better to resolve to Object and do any conversion later on.

In general I think it's better to pass configurations just as is (byte[]/Object) and do required conversion right before resolving for the service.

Will be happy to provide more details if needed.

I think this may also require enhancement request to micronaut-core.

Environment Information

  • gcr.io/distroless/java17
  • JDK17

Example Application

No response

Version

3.3.0

@dima-starosud dima-starosud changed the title Secrets with non-printable characters are not properly Secrets with non-printable characters are corrupted on the app side Feb 11, 2022
@alvarosanchez alvarosanchez added the type: bug Something isn't working label Feb 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants