Files
web-hosts/domains/coppertone.tech/audit-reports/security-audit/authentication-20251123-092507.txt
2025-12-26 13:38:04 +01:00

134 lines
18 KiB
Plaintext

# Authentication Audit - 20251123-092507
== JWT Implementation ==
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:16: "github.com/golang-jwt/jwt/v5"
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:86: jwtSecret []byte
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:194: jwtSecret = []byte(strings.TrimSpace(os.Getenv("JWT_SECRET")))
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:195: if len(jwtSecret) < 32 {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:196: log.Fatal("JWT_SECRET must be set and at least 32 characters")
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:218: tokenString := strings.TrimPrefix(authHeader, "Bearer ")
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:219: if tokenString == authHeader {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:224: token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:225: if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:228: return jwtSecret, nil
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:231: if err != nil || !token.Valid {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:232: http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:236: claims, ok := token.Claims.(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:238: http.Error(w, "Invalid token claims", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:255: tokenString := strings.TrimPrefix(authHeader, "Bearer ")
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:256: if tokenString == authHeader {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:261: token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:262: if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:265: return jwtSecret, nil
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:268: if err != nil || !token.Valid {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:273: claims, ok := token.Claims.(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:286: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:306:func extractRoles(claims jwt.MapClaims) ([]string, error) {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:330:func hasRole(claims jwt.MapClaims, role string) bool {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:347:func getUserID(claims jwt.MapClaims) int {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:357:func getUserName(claims jwt.MapClaims) string {
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:570: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:610: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:654: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:693: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:759: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:803: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:843: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:889: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:916: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:970: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1023: claims := r.Context().Value(userContextKey).(jwt.MapClaims)
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:17: "github.com/golang-jwt/jwt/v5"
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:97: ensureJWTSecret()
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:244:func ensureJWTSecret() {
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:245: secret := strings.TrimSpace(os.Getenv("JWT_SECRET"))
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:247: log.Fatal("JWT_SECRET must be set and at least 32 characters")
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:251:// authMiddleware validates JWT token and extracts user info
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:260: tokenString := strings.TrimPrefix(authHeader, "Bearer ")
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:261: if tokenString == authHeader {
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:262: http.Error(w, "Invalid authorization format. Expected: Bearer <token>", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:266: // Parse and validate JWT token
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:267: token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:269: if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:270: return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
== Token Expiration Settings ==
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:226: return nil, fmt.Errorf("unexpected signing method")
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:232: http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:263: return nil, fmt.Errorf("unexpected signing method")
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main_test.go:27: expected := "ok\n"
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main_test.go:28: if rr.Body.String() != expected {
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main_test.go:29: t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
/home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:270: return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
/home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main_test.go:27: expected := "ok\n"
/home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main_test.go:28: if rr.Body.String() != expected {
/home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main_test.go:29: t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
/home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:264: return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:57: // This will fail if JWT_SECRET is not set, which is expected in test environment
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:61: // If JWT_SECRET is not set, we expect an error
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:14: "regexp"
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:76: // Reset window if expired
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:107: // Reset window if expired
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:164:var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:451: // Default to restrictive in production - set CORS_ALLOW_ORIGIN explicitly
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1146: return nil, fmt.Errorf("unexpected signing method")
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1152: http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1217: "exp": time.Now().Add(time.Hour * 24).Unix(),
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1243: return nil, errors.New("roles claim has unexpected type")
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1290: "exp": time.Now().Add(time.Hour).Unix(),
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:256: return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:262: http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:473: // Don't expose review details to public
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:518: // Don't expose review details to public
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:990: // Don't expose internal details to public
/home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1035: // Don't expose internal details to public
/home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:10: "regexp"
/home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:215: return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
/home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:508: emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
== Password Hashing ==
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:23: "golang.org/x/crypto/bcrypt"
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:160: maxPasswordLength = 72 // bcrypt limit
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:556: passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:785: if err := bcrypt.CompareHashAndPassword([]byte(passwordHash), []byte(req.Password)); err != nil {
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:906: passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1296: hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
/home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1304: return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
== Weak Hashing (MD5, SHA1) ==
None found - good
== Session Management ==
/home/administrator/projects/coppertone.tech/frontend/src/stores/trustBusiness.ts:865: options: ['Terms of Use', 'Privacy Policy', 'Cookie Policy', 'Refund Policy', 'Shipping Policy'],
/home/administrator/projects/coppertone.tech/frontend/src/stores/auth.ts:75: 'session expired': {
/home/administrator/projects/coppertone.tech/frontend/src/stores/auth.ts:77: message: 'Your session has expired. Please sign in again.'
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/types.ts:69: * If `false`, will also ignore cookies in the CORS response.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/types.ts:149: * a CORS request, _OR_ when cookies are to be ignored by the CORS response, set to `false`.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/types.ts:156: * The name of your site's XSRF cookie.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/types.ts:158: xsrfCookieName?: string;
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/types.ts:161: * The name of a custom header that you can use to send your XSRF cookie.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:370: // Allow users to provide their XSRF cookie name and the name of a custom header to use to
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:371: // send the cookie.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:372: const { withCredentials, xsrfCookieName, xsrfHeaderName } = config;
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:373: if ((withCredentials || !crossDomain) && xsrfCookieName && xsrfHeaderName) {
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:374: const xsrfCookie = document?.cookie.match(new RegExp(`(^|;\\s*)(${xsrfCookieName})=([^;]*)`))?.pop() ?? '';
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:375: if (xsrfCookie) {
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/src/internal/ajax/ajax.ts:376: headers[xsrfHeaderName] = xsrfCookie;
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/dist/types/internal/ajax/types.d.ts:56: * If `false`, will also ignore cookies in the CORS response.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/dist/types/internal/ajax/types.d.ts:125: * a CORS request, _OR_ when cookies are to be ignored by the CORS response, set to `false`.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/dist/types/internal/ajax/types.d.ts:131: * The name of your site's XSRF cookie.
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/dist/types/internal/ajax/types.d.ts:133: xsrfCookieName?: string;
/home/administrator/projects/coppertone.tech/frontend/node_modules/rxjs/dist/types/internal/ajax/types.d.ts:135: * The name of a custom header that you can use to send your XSRF cookie.
/home/administrator/projects/coppertone.tech/frontend/node_modules/globals/index.d.ts:922: readonly 'sessionStorage': false;
/home/administrator/projects/coppertone.tech/frontend/node_modules/axios/index.d.ts:77: getSetCookie(): string[];
/home/administrator/projects/coppertone.tech/frontend/node_modules/axios/index.d.ts:99: "set-cookie": string[];
/home/administrator/projects/coppertone.tech/frontend/node_modules/axios/index.d.ts:336: xsrfCookieName?: string;
/home/administrator/projects/coppertone.tech/frontend/node_modules/axios/index.d.ts:374: sessionTimeout?: number;
/home/administrator/projects/coppertone.tech/frontend/node_modules/ansi-escapes/index.d.ts:11: - `N%`: N percent of the session's width or height.
/home/administrator/projects/coppertone.tech/frontend/node_modules/ansi-escapes/index.d.ts:21: - `N%`: N percent of the session's width or height.
/home/administrator/projects/coppertone.tech/frontend/node_modules/log-update/index.d.ts:38: Persist the logged output. Useful if you want to start a new log session below the current one.
/home/administrator/projects/coppertone.tech/frontend/node_modules/tough-cookie/dist/getPublicSuffix.d.ts:11: * In testing scenarios it's common to configure the cookie store with so that `http://localhost` can be used as a domain:
/home/administrator/projects/coppertone.tech/frontend/node_modules/tough-cookie/dist/getPublicSuffix.d.ts:31: * name upon which a cookie can be set.
== Refresh Token Implementation ==
No refresh token found - sessions may expire abruptly