{"record":{"id":"3e1e720732b7587f","repo":"iflytek/astron-agent","slug":"toolbox-url-short-not-supported","errorCode":"TOOLBOX_URL_SHORT_NOT_SUPPORTED","errorMessage":"TOOLBOX_URL_SHORT_NOT_SUPPORTED","messagePattern":"TOOLBOX_URL_SHORT_NOT_SUPPORTED","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"warning","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/tool/UrlCheckTool.java","lineNumber":276,"sourceCode":"    }\n\n    /**\n     * Blocks common short links (short links easily used for redirect bypass and phishing).\n     *\n     * @param shortUrl the URL to check for short link domains\n     * @throws IOException if URL processing fails\n     * @throws BusinessException if the URL is a known short link\n     */\n    public void resolveShortLink(String shortUrl) throws IOException {\n        if (StringUtils.isBlank(shortUrl))\n            return;\n\n        Matcher matcher = DOMAIN_PATTERN.matcher(shortUrl);\n        if (matcher.find()) {\n            String domain = matcher.group(1);\n            String asciiDomain = IDN.toASCII(domain).toLowerCase(Locale.ROOT);\n            if (SHORT_LINK_DOMAINS.contains(asciiDomain)) {\n                throw new BusinessException(ResponseEnum.TOOLBOX_URL_SHORT_NOT_SUPPORTED);\n            }\n        }\n    }\n\n    /**\n     * Only allows HTTP/HTTPS protocols. Silently returns on parsing exception, let upper layer handle\n     * uniformly.\n     *\n     * @param url the URL to validate protocol\n     * @throws BusinessException if protocol is not HTTP or HTTPS\n     */\n    public void checkHttpOrHttps(String url) {\n        try {\n            URL parsed = new URL(url);\n            String protocol = parsed.getProtocol();\n            if (!\"http\".equalsIgnoreCase(protocol) && !\"https\".equalsIgnoreCase(protocol)) {\n                throw new BusinessException(ResponseEnum.TOOLBOX_URL_HTTP_HTTPS_ONLY);\n            }","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/tool/UrlCheckTool.java#L258-L294","documentation":"UrlCheckTool.resolveShortLink throws TOOLBOX_URL_SHORT_NOT_SUPPORTED when the URL's host matches a known URL-shortener domain (bit.ly, tinyurl.com, t.co, is.gd, t.ly, rebrandly.com, monojson.com, t.cn, url.cn, dwz.cn). Short links are blocked because they hide the real destination and enable redirect-based SSRF/phishing bypass.","triggerScenarios":"Calling checkUrl/resolveShortLink with a URL whose authority (the https?://([^/]+) capture, compared after IDN.toASCII and lowercasing) equals one of the SHORT_LINK_DOMAINS entries, e.g. \"https://bit.ly/3xYz\" or \"http://t.cn/abc\".","commonSituations":"Users pasting shortened links shared on social media or in chat, marketing content with shortened tracking URLs, or automation that shortens long URLs before submitting them to the toolbox.","solutions":["Expand the short link to its final destination URL (follow the redirect manually or with a curl -I) and submit the full URL instead.","Ask the link author for the original long URL.","If the domain is a legitimate non-shortener being falsely matched, note the domain list is a fixed constant (SHORT_LINK_DOMAINS) and requires a code change to extend.","Do not try to obfuscate the shortener domain (e.g. with userInfo or alternative encodings); the other checks (symbolCheck etc.) will reject those too."],"exampleFix":"// before\nurlCheckTool.checkUrl(\"https://bit.ly/3xYzAbC\"); // TOOLBOX_URL_SHORT_NOT_SUPPORTED\n// after: resolve the redirect first, then submit the destination\n// curl -sI https://bit.ly/3xYzAbC | grep -i location -> https://example.com/real/page\nurlCheckTool.checkUrl(\"https://example.com/real/page\");","handlingStrategy":"validation","validationCode":"static final java.util.Set<String> SHORT_LINKS = java.util.Set.of(\"bit.ly\",\"tinyurl.com\",\"t.co\",\"rebrandly.com\",\"is.gd\",\"t.ly\",\"monojson.com\",\"t.cn\",\"url.cn\",\"dwz.cn\");\nstatic boolean isShortLink(String url) {\n    java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"https?://([^/]+)\").matcher(url);\n    return m.find() && SHORT_LINKS.contains(m.group(1).toLowerCase(java.util.Locale.ROOT));\n}\n// call only if !isShortLink(url)","typeGuard":"null","tryCatchPattern":"try {\n    urlCheckTool.checkUrl(url);\n} catch (BusinessException e) {\n    if (\"TOOLBOX_URL_SHORT_NOT_SUPPORTED\".equals(e.getCode())) {\n        // prompt user to provide the expanded destination URL\n    } else { throw e; }\n}","preventionTips":["Expand short links (HEAD request / redirect follow) before submitting.","Ask authors for original URLs instead of shortened tracking links.","Sanitize inbound content (chat/marketing) to strip shortener domains upstream.","Remember the shortener list is a fixed code constant; keep up to date via code review."],"tags":["url","short-link","security","ssrf"],"backgroundTag":"invalid-url","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"}