{"record":{"id":"886a0a3ac9dc1e6f","repo":"iflytek/astron-agent","slug":"invalid-workflow-gateway-identity","errorCode":null,"errorMessage":"invalid workflow gateway identity","messagePattern":"invalid workflow gateway identity","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"console/backend/commons/src/main/java/com/iflytek/astron/console/commons/security/WorkflowGatewayIdentity.java","lineNumber":55,"sourceCode":"        }\n        return path;\n    }\n\n    /** Sign {@code method + newline + path + newline + appId + newline + epochSeconds}. */\n    public static String sign(\n            String configuredKey,\n            String method,\n            String path,\n            String appId,\n            long epochSeconds) {\n        String internalKey = WorkflowInternalApiKey.requireConfigured(configuredKey);\n        if (!POST.equals(method)\n                || !PUBLIC_WORKFLOW_PATHS.contains(path)\n                || StringUtils.isBlank(appId)\n                || appId.indexOf('\\r') >= 0\n                || appId.indexOf('\\n') >= 0\n                || epochSeconds < 0) {\n            throw new IllegalArgumentException(\"invalid workflow gateway identity\");\n        }\n        String payload = method + '\\n' + path + '\\n' + appId + '\\n' + epochSeconds;\n        try {\n            Mac mac = Mac.getInstance(HMAC_SHA_256);\n            mac.init(new SecretKeySpec(\n                    internalKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA_256));\n            return HexFormat.of()\n                    .formatHex(\n                            mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)));\n        } catch (GeneralSecurityException exception) {\n            throw new IllegalStateException(\n                    \"Unable to sign workflow gateway identity\", exception);\n        }\n    }\n}\n","sourceCodeStart":37,"sourceCodeEnd":71,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/commons/src/main/java/com/iflytek/astron/console/commons/security/WorkflowGatewayIdentity.java#L37-L71","documentation":"WorkflowGatewayIdentity.sign validates all identity inputs before computing the HMAC-SHA-256: method must be POST, path whitelisted, appId non-blank with no CR/LF, epochSeconds non-negative. Any violation throws IllegalArgumentException to prevent malformed or injection-prone signature payloads.","triggerScenarios":"Calling sign with a non-POST method; blank or null appId; appId containing \\r or \\n (header-injection vector); negative epochSeconds from a broken clock or bad argument; non-whitelisted path passed directly to sign.","commonSituations":"Clock skew or misconfigured time source yielding negative timestamps; app IDs read from untrusted input with embedded newlines; refactors calling sign with arbitrary methods/paths; integration code bypassing requireAuthorizedPath.","solutions":["Sanitize/validate the appId source — trim and reject values containing CR/LF before calling sign","Use System.currentTimeMillis()/1000 (or equivalent) so epochSeconds is non-negative","Only call sign after requireAuthorizedPath returns the whitelisted path, and always with POST","Catch IllegalArgumentException at the gateway boundary and return 400"],"exampleFix":"// before\nString appId = header;\nString sig = WorkflowGatewayIdentity.sign(\"POST\", path, appId, -1);\n// after\nString appId = StringUtils.trimToEmpty(header);\nif (StringUtils.isBlank(appId) || appId.indexOf('\\n') >= 0 || appId.indexOf('\\r') >= 0) {\n    throw new BusinessException(ResponseEnum.PARAM_ERROR);\n}\nlong epochSeconds = System.currentTimeMillis() / 1000;\nString sig = WorkflowGatewayIdentity.sign(\"POST\", path, appId, epochSeconds);","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(appId) || appId.indexOf('\\n') >= 0 || appId.indexOf('\\r') >= 0 || epochSeconds < 0) throw new BusinessException(ResponseEnum.PARAM_ERROR);","typeGuard":"boolean signable(String appId, long epochSeconds) { return StringUtils.isNotBlank(appId) && appId.indexOf('\\r') < 0 && appId.indexOf('\\n') < 0 && epochSeconds >= 0; }","tryCatchPattern":"try { sig = WorkflowGatewayIdentity.sign(\"POST\", path, appId, epochSeconds); } catch (IllegalArgumentException e) { return badRequest(\"invalid gateway identity\"); }","preventionTips":["Derive epochSeconds from System.currentTimeMillis()/1000","Sanitize appId inputs (trim, reject CR/LF)","Always sign the path returned by requireAuthorizedPath"],"tags":["validation","hmac","header-injection"],"backgroundTag":"invalid-argument-value","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}