{"record":{"id":"f7c638e3b8277de0","repo":"apache/shenyu","slug":"key-or-data-is-null","errorCode":null,"errorMessage":"Key or data is null.","messagePattern":"Key or data is null\\.","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"shenyu-common/src/main/java/org/apache/shenyu/common/utils/SignUtils.java","lineNumber":59,"sourceCode":"            SIGN_MD5, (key, data) -> DigestUtils.md5Hex(data + key),\n            SIGN_HMD5, HmacHexUtils::hmacMd5Hex,\n            SIGN_HS256, HmacHexUtils::hmacSha256Hex,\n            SIGN_HS512, HmacHexUtils::hmacSha512Hex\n    );\n\n    /**\n     * Returns signature of data as hex string (lowercase).\n     *\n     * @param algorithmName the name of sign algorithm\n     * @param key           key\n     * @param data          data to sign\n     * @return signature\n     * @throws NullPointerException          if key or data is null\n     * @throws UnsupportedOperationException if algorithmName isn't supported\n     */\n    public static String sign(final String algorithmName, final String key, final String data) {\n        if (Objects.isNull(key) || Objects.isNull(data)) {\n            throw new NullPointerException(\"Key or data is null.\");\n        }\n\n        return Optional.ofNullable(SIGN_FUNCTION_MAP.get(algorithmName))\n                .orElseThrow(() -> new UnsupportedOperationException(\"unsupported sign algorithm:\" + algorithmName))\n                .sign(key, data);\n    }\n\n    /**\n     * Generate key string.\n     *\n     * @return the string\n     */\n    public static String generateKey() {\n        return UUID.randomUUID().toString().replaceAll(\"-\", \"\").toUpperCase();\n    }\n\n    @FunctionalInterface\n    private interface SignFunction {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-common/src/main/java/org/apache/shenyu/common/utils/SignUtils.java#L41-L77","documentation":"SignUtils.sign computes HMAC-style signatures via a map of supported algorithms. It explicitly throws NullPointerException when either the secret key or the data is null, and UnsupportedOperationException for unknown algorithm names. This fails fast instead of letting the signing function NPE deep inside.","triggerScenarios":"Calling SignUtils.sign(algorithmName, key, data) with a null key or null data string, e.g. when the configured secret is missing or the body to sign was not extracted.","commonSituations":"Sign plugin configured without a secret key; request body empty/null when building the signature; environment/config property for the key not set; upstream clients sending requests that bypass key extraction.","solutions":["Ensure the signing key is configured and non-null before calling sign.","Null-check/guard the data (e.g. default empty string) prior to signing.","Verify the sign plugin's selector/rule configuration contains the secret key.","If null data is legitimate, decide on a canonical representation (empty string) and normalize inputs first."],"exampleFix":"// before\nString sign = SignUtils.sign(\"HmacSHA256\", config.getKey(), body); // body may be null\n// after\nString sign = SignUtils.sign(\"HmacSHA256\",\n        Objects.requireNonNull(config.getKey(), \"sign key missing\"),\n        body == null ? \"\" : body);","handlingStrategy":"validation","validationCode":"if (key == null || data == null) throw new IllegalArgumentException(\"key and data must be non-null before signing\");\nif (!SIGN_FUNCTION_MAP.containsKey(algorithmName)) throw new IllegalArgumentException(\"unsupported algorithm: \" + algorithmName);","typeGuard":"boolean signable = key != null && data != null && algorithmName != null;","tryCatchPattern":"try { return SignUtils.sign(alg, key, data); } catch (NullPointerException | UnsupportedOperationException e) { LOG.error(\"sign failed: {}\", e.getMessage()); throw new SignatureException(e); }","preventionTips":["Fail fast on missing signing key at config load time","Default null body to empty string before signing","Keep the algorithm whitelist documented for plugin config","Validate sign plugin config in admin before publishing rules"],"tags":["signing","null-check","security","plugin"],"backgroundTag":"null-argument","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}