@@ -28,6 +28,7 @@ namespace ICSharpCode.ILSpy.Updates
2828{
2929 internal static class UpdateService
3030 {
31+ const string ReleaseTagBaseUrl = "https://github.com/icsharpcode/ILSpy/releases/tag/" ;
3132 static readonly Uri UpdateUrl = new Uri ( "https://icsharpcode.github.io/ILSpy/updates.xml" ) ;
3233 const string band = "stable" ;
3334
@@ -39,15 +40,32 @@ public static async Task<AvailableVersionInfo> GetLatestVersionAsync()
3940 UseProxy = true ,
4041 UseDefaultCredentials = true
4142 } ) ;
43+
44+ // Issue #3707: Remove 301 redirect logic once ilspy.net CNAME gone
4245 string data = await GetWithRedirectsAsync ( client , UpdateUrl ) . ConfigureAwait ( false ) ;
4346
4447 XDocument doc = XDocument . Load ( new StringReader ( data ) ) ;
4548 var bands = doc . Root . Elements ( "band" ) . ToList ( ) ;
4649 var currentBand = bands . FirstOrDefault ( b => ( string ) b . Attribute ( "id" ) == band ) ?? bands . First ( ) ;
4750 Version version = new Version ( ( string ) currentBand . Element ( "latestVersion" ) ) ;
48- string url = ( string ) currentBand . Element ( "downloadUrl" ) ;
49- if ( ! ( url . StartsWith ( "http://" , StringComparison . Ordinal ) || url . StartsWith ( "https://" , StringComparison . Ordinal ) ) )
50- url = null ; // don't accept non-urls
51+
52+ string url = null ;
53+ string releaseTag = ( string ) currentBand . Element ( "releaseTag" ) ;
54+
55+ if ( releaseTag != null )
56+ {
57+ url = ReleaseTagBaseUrl + releaseTag ;
58+ // Prevent path traversal: normalize the URI and verify it still starts with the expected base
59+ if ( ! new Uri ( url ) . AbsoluteUri . StartsWith ( ReleaseTagBaseUrl , StringComparison . Ordinal ) )
60+ url = null ;
61+ }
62+ else
63+ {
64+ // Issue #3707: Remove else branch fallback logic once releaseTag version has shipped + 6 months
65+ url = ( string ) currentBand . Element ( "downloadUrl" ) ;
66+ if ( ! ( url . StartsWith ( "http://" , StringComparison . Ordinal ) || url . StartsWith ( "https://" , StringComparison . Ordinal ) ) )
67+ url = null ; // don't accept non-urls
68+ }
5169
5270 LatestAvailableVersion = new AvailableVersionInfo { Version = version , DownloadUrl = url } ;
5371 return LatestAvailableVersion ;
0 commit comments