55d8434f35
- StaffPermission enum (8 granular permissions) - StaffAccount JPA entity with permissions collection - RevokedToken entity for JWT blacklisting - Flyway V3 migration (staff_accounts, staff_account_permissions, revoked_tokens) - StaffAccountRepository + RevokedTokenRepository - TokenRevocationService with Caffeine cache (60s TTL, 10k max) - StaffPermissionChecker SpEL bean (@staffPermissions.has) - PreventionOfficerChecker SpEL bean (@preventionOfficer.check) - JwtService: added jti claim + generateStaffAccessToken + extractJti/extractPermissions - JwtAuthFilter: token blacklist check via TokenRevocationService - SecurityConfig: STAFF role added to endpoint matchers - Controllers updated with @PreAuthorize for fine-grained access - TokenCleanupScheduler (daily 03:00 cleanup of expired revoked tokens) - Caffeine dependency added to cannamanage-service - Unit tests: StaffPermissionCheckerTest (7), TokenRevocationServiceTest (9)
2 lines
13 KiB
JSON
2 lines
13 KiB
JSON
{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json","version": "2.1.0","runs": [{"tool": {"driver" : {"name" : "SnykCode","semanticVersion" : "1.1305.1","version" : "1.1305.1","informationUri" : "https://docs.snyk.io/","rules" : [{"id": "java/DisablesCSRFProtection","name": "DisablesCSRFProtection","shortDescription": {"text": "Cross-Site Request Forgery (CSRF)"},"defaultConfiguration": {"level": "error"},"help": {"markdown": "\n## Details\nCross-site request forgery is an attack in which a malicious third party takes advantage of a user's authenticated credentials (such as a browser cookie) to impersonate that trusted user and perform unauthorized actions. The web application server cannot tell the difference between legitimate and malicious requests. This type of attack generally begins by tricking the user with a social engineering attack, such as a link or popup that the user inadvertently clicks, causing an unauthorized request to be sent to the web server. Consequences vary: At a standard user level, attackers can change passwords, transfer funds, make purchases, or connect with contacts; from an administrator account, attackers can then make changes to or even take down the app itself.\n\n## Best practices for prevention\n* Use development frameworks that defend against CSRF, using a nonce, hash, or some other security device to the URL and/or to forms.\n* Implement secure, unique, hidden tokens that are checked by the server each time to validate state-change requests.\n* Never assume that authentication tokens and session identifiers mean a request is legitimate.\n* Understand and implement other safe-cookie techniques, such as double submit cookies.\n* Terminate user sessions when not in use, including automatic timeout.\n* Ensure rigorous coding practices and defenses against other commonly exploited CWEs, since cross-site scripting (XSS), for example, can be used to bypass defenses against CSRF.","text": ""},"properties": {"tags": ["java","DisablesCSRFProtection","Security"],"categories": ["Security"],"exampleCommitFixes": [{"commitURL": "https://github.com/13482477/JFDF/commit/3326a94a203ab334e9185d93beadc38b9c93b100?diff=split#diff-a9f9136673bc42f9fcd901899a430de1862ad2f7cda4150ce17bbddbd5909851L-1","lines": [{"line": "http\r\n","lineNumber": 37,"lineChange": "none"},{"line": ".authorizeRequests()\r\n","lineNumber": 38,"lineChange": "none"},{"line": "\t.antMatchers(new String[] {\r\n","lineNumber": 39,"lineChange": "none"},{"line": "\t\t\t\"/login\",\r\n","lineNumber": 40,"lineChange": "none"},{"line": "\t\t\t\"/logout\",\r\n","lineNumber": 41,"lineChange": "none"},{"line": "\t\t\t\"/**/*.css\",\r\n","lineNumber": 42,"lineChange": "none"},{"line": "\t\t\t\"/**/*.js\",\r\n","lineNumber": 43,"lineChange": "none"},{"line": "\t\t\t\"/**/*.woff\",\r\n","lineNumber": 44,"lineChange": "none"},{"line": "\t\t\t\"/**/*.woff2\",\r\n","lineNumber": 45,"lineChange": "none"},{"line": "\t\t\t\"/**/*.css.map\",\r\n","lineNumber": 46,"lineChange": "none"},{"line": "\t\t\t\"/**/*.ttf\",\r\n","lineNumber": 47,"lineChange": "none"},{"line": "\t\t\t\"/**/*.png\",\r\n","lineNumber": 48,"lineChange": "none"},{"line": "\t\t\t\"/**/*.jpg\",\r\n","lineNumber": 49,"lineChange": "none"},{"line": "\t\t\t\"/**/*.jpeg\",\r\n","lineNumber": 50,"lineChange": "none"},{"line": "\t\t\t\"/**/*.gif\",\r\n","lineNumber": 51,"lineChange": "none"},{"line": "\t\t\t}).permitAll()\r\n","lineNumber": 52,"lineChange": "none"},{"line": "\t.anyRequest().authenticated()\r\n","lineNumber": 53,"lineChange": "none"},{"line": "\t.and()\r\n","lineNumber": 54,"lineChange": "none"},{"line": ".formLogin()\r\n","lineNumber": 55,"lineChange": "none"},{"line": "\t.loginPage(\"/login\")\r\n","lineNumber": 56,"lineChange": "none"},{"line": "\t.defaultSuccessUrl(\"/index\")\r\n","lineNumber": 57,"lineChange": "none"},{"line": "\t.failureHandler(new FeedbackLoginInfoAuthenticationFailureHandler(\"/login\"))\r\n","lineNumber": 58,"lineChange": "none"},{"line": "\t.and()\r\n","lineNumber": 59,"lineChange": "none"},{"line": ".logout()\r\n","lineNumber": 60,"lineChange": "none"},{"line": "\t.logoutUrl(\"/logout\")\r\n","lineNumber": 61,"lineChange": "none"},{"line": "\t.logoutSuccessUrl(\"/login\")\r\n","lineNumber": 62,"lineChange": "none"},{"line": "\t.and()\r\n","lineNumber": 63,"lineChange": "none"},{"line": ".csrf()\r\n","lineNumber": 64,"lineChange": "removed"},{"line": "\t.disable();\r\n","lineNumber": 65,"lineChange": "removed"},{"line": ".csrf();\r\n","lineNumber": 64,"lineChange": "added"}]},{"commitURL": "https://github.com/mraible/java-webapp-security-examples/commit/1ae83aeb6975a107dcdb616eeae63bc846fcadaf?diff=split#diff-b8cb20d5732c784ae693cb1cd9ecb813e912a21fe570c581998875276a2a642dL-1","lines": [{"line": "http\n","lineNumber": 23,"lineChange": "none"},{"line": " .csrf().disable()\n","lineNumber": 24,"lineChange": "removed"},{"line": " .csrf().and()\n","lineNumber": 24,"lineChange": "added"}]},{"commitURL": "https://github.com/jgribonvald/demo-spring-security-cas/commit/3b1ee5ecc5e718513127355b884c165bb4936c7f?diff=split#diff-4ead997b1df6dd1b785b7ba2dbcb18dfb6f6624a1997e5642b016adf46e69d08L-1","lines": [{"line": "\t\t/**\n","lineNumber": 162,"lineChange": "removed"},{"line": "\t\t * <session-management session-fixation-protection=\"newSession\"/>\n","lineNumber": 163,"lineChange": "removed"},{"line": "\t\t */\n","lineNumber": 164,"lineChange": "removed"},{"line": "\t\thttp.sessionManagement().sessionFixation().changeSessionId();\n","lineNumber": 165,"lineChange": "removed"},{"line": "\n","lineNumber": 166,"lineChange": "removed"},{"line": "\t\thttp.csrf().disable();\n","lineNumber": 167,"lineChange": "removed"},{"line": "\t\t// http.csrf();\n","lineNumber": 171,"lineChange": "added"}]}],"exampleCommitDescriptions": [],"precision": "very-high","repoDatasetSize": 42,"cwe": ["CWE-352"]}},{"id": "java/HardcodedPassword/test","name": "HardcodedPassword/test","shortDescription": {"text": "Use of Hardcoded Passwords"},"defaultConfiguration": {"level": "note"},"help": {"markdown": "\n## Details\n\nDevelopers may use hardcoded passwords during development to streamline setup or simplify authentication while testing. Although these passwords are intended to be removed before deployment, they are sometimes inadvertently left in the code. This introduces serious security risks, especially if the password grants elevated privileges or is reused across multiple systems.\n\nAn attacker who discovers a hardcoded password can potentially gain unauthorized access, escalate privileges, exfiltrate sensitive data, or disrupt service availability. If the password is reused across different environments or applications, the compromise can spread quickly and broadly.\n\n## Best practices for prevention\n* Plan software architecture such that keys and passwords are always stored outside the code, wherever possible.\n* Plan encryption into software architecture for all credential information and ensure proper handling of keys, credentials, and passwords.\n* Prompt for a secure password on first login rather than hard-code a default password.\n* If a hardcoded password or credential must be used, limit its use, for example, to system console users rather than via the network.\n* Use strong hashes for inbound password authentication, ideally with randomly assigned salts to increase the difficulty level in case of brute-force attack.","text": ""},"properties": {"tags": ["java","HardcodedPassword","Security","InTest"],"categories": ["Security","InTest"],"exampleCommitFixes": [{"commitURL": "https://github.com/clowee/OpenSZZ-Cloud-Native/commit/ee429faf9d384074cf33515eda2a52e4e85ef061?diff=split#diff-a125fdf9d37b8daa4d9f0a7a46aedd416a80a49936bdee4bae40db3f3eef22deL-1","lines": [{"line": "final String username = \"noreply.openszz@gmail.com\";\n","lineNumber": 19,"lineChange": "removed"},{"line": "final String password = \"Aa30011992\";\n","lineNumber": 20,"lineChange": "removed"},{"line": "final String username = System.getenv(\"EMAIL\");\n","lineNumber": 19,"lineChange": "added"},{"line": "final String password = System.getenv(\"PWD\");\n","lineNumber": 20,"lineChange": "added"}]},{"commitURL": "https://github.com/winstonli/writelatex-git-bridge/commit/1117c70f31cee7d9a84c565c143f353d8bbab19e?diff=split#diff-16d090e60dcd386546c2164ae454bd356cbf326d715a66796582e8c003d8af10L-1","lines": [{"line": " public static void setBasicAuth(String username, String password) {\n","lineNumber": 27,"lineChange": "added"},{"line": " USERNAME = username;\n","lineNumber": 28,"lineChange": "added"},{"line": " PASSWORD = password;\n","lineNumber": 29,"lineChange": "added"},{"line": " }\n","lineNumber": 30,"lineChange": "added"},{"line": "\n","lineNumber": 31,"lineChange": "added"},{"line": " public static void setBaseURL(String baseURL) {\n","lineNumber": 32,"lineChange": "added"},{"line": " BASE_URL = baseURL;\n","lineNumber": 33,"lineChange": "added"},{"line": " }\n","lineNumber": 34,"lineChange": "added"},{"line": "\n","lineNumber": 35,"lineChange": "added"}]},{"commitURL": "https://github.com/CheckChe0803/flink-recommandSystem-demo/commit/bbe348d12bc76858d8c0878f2a89ccc0f1e7b05b?diff=split#diff-7cac3b1a67764486d11265840a420739f0339a6cc8ff947d192de102366f8acaL-1","lines": [{"line": "private static String URL = \"jdbc:mysql://localhost/con?serverTimezone=GMT%2B8\";\n","lineNumber": 6,"lineChange": "removed"},{"line": "private static String NAME = \"root\";\n","lineNumber": 7,"lineChange": "removed"},{"line": "private static String PASS = \"root\";\n","lineNumber": 8,"lineChange": "removed"},{"line": "private static String URL = Property.getStrValue(\"mysql.url\");\n","lineNumber": 8,"lineChange": "added"},{"line": "private static String NAME = Property.getStrValue(\"mysql.name\");\n","lineNumber": 9,"lineChange": "added"},{"line": "private static String PASS = Property.getStrValue(\"mysql.pass\");\n","lineNumber": 10,"lineChange": "added"},{"line": "private static Statement stmt;\n","lineNumber": 11,"lineChange": "none"},{"line": "static {\n","lineNumber": 12,"lineChange": "none"},{"line": " try {\n","lineNumber": 13,"lineChange": "none"},{"line": " Class.forName(\"com.mysql.cj.jdbc.Driver\");\n","lineNumber": 14,"lineChange": "none"},{"line": " Connection conn = DriverManager.getConnection(URL, NAME, PASS);\n","lineNumber": 15,"lineChange": "none"}]}],"exampleCommitDescriptions": [],"precision": "very-high","repoDatasetSize": 74,"cwe": ["CWE-798","CWE-259"]}}]}},"results": [{"ruleId": "java/DisablesCSRFProtection","ruleIndex": 0,"level": "error","message": {"text":"CSRF protection is disabled by disable. This allows the attackers to execute requests on a user's behalf.","markdown":"CSRF protection is disabled by {0}. This allows the attackers to execute requests on a user's behalf.","arguments": ["[disable](0)"]},"locations": [{ "id": 0, "physicalLocation": {"artifactLocation": { "uri": "cannamanage-api/src/main/java/de/cannamanage/api/security/SecurityConfig.java", "uriBaseId": "%SRCROOT%"},"region": { "startLine":61, "endLine":63, "startColumn":9, "endColumn":22} }}],"fingerprints": {"identity": "e7bfa036-d8c0-453d-abd2-239ced27a331","0": "04cfdbea297f59d0da47ea9332da5f4ba165056eae82575b6d9250f28537295d","1": "b5099633.fd6a5963.13c31930.e22980a8.f2a5bca1.4431cad1.7b4155dd.54d46e25.b5099633.fd6a5963.13c31930.de031890.f0e1baa5.102e2858.3953228b.f7c40842","snyk/asset/finding/v1": "e7bfa036-d8c0-453d-abd2-239ced27a331"},"codeFlows": [{"threadFlows": [{"locations": [{"location": {"id": 0,"physicalLocation": {"artifactLocation": { "uri": "cannamanage-api/src/main/java/de/cannamanage/api/security/SecurityConfig.java", "uriBaseId": "%SRCROOT%"},"region": { "startLine":63, "endLine":63, "startColumn":31, "endColumn":43}}}}]}]}],"properties": {"isAutofixable": true,"priorityScore": 800,"priorityScoreFactors": [ {"label": true,"type": "hotFileCodeFlow" }, {"label": true,"type": "fixExamples" }]}},{"ruleId": "java/HardcodedPassword/test","ruleIndex": 1,"level": "note","message": {"text":"Do not hardcode passwords in code. Found hardcoded password used in here.","markdown":"Do not hardcode passwords in code. Found hardcoded password used in {0}.","arguments": ["[here](0)"]},"locations": [{ "id": 0, "physicalLocation": {"artifactLocation": { "uri": "cannamanage-api/src/test/java/de/cannamanage/api/controller/AuthControllerIntegrationTest.java", "uriBaseId": "%SRCROOT%"},"region": { "startLine":48, "endLine":48, "startColumn":49, "endColumn":65} }}],"fingerprints": {"identity": "a8ecbbe1-6bb2-4f4f-9ba8-9cf1985f0f1b","0": "a7b20b1967684ddcb44b5af14789ff3f8bd7a5e89329849d356794ce1e1802e6","1": "51f4bbec.dd05ec30.c0c79380.de031890.8b2d3351.248bce3c.3f71d1e7.87dfd8cc.51f4bbec.8b9ac446.c0c79380.de031890.5b39032a.248bce3c.c66d287d.54d46e25","snyk/asset/finding/v1": "a8ecbbe1-6bb2-4f4f-9ba8-9cf1985f0f1b"},"codeFlows": [{"threadFlows": [{"locations": [{"location": {"id": 0,"physicalLocation": {"artifactLocation": { "uri": "cannamanage-api/src/test/java/de/cannamanage/api/controller/AuthControllerIntegrationTest.java", "uriBaseId": "%SRCROOT%"},"region": { "startLine":48, "endLine":48, "startColumn":49, "endColumn":65}}}}]}]}],"properties": {"isAutofixable": true,"priorityScore": 400,"priorityScoreFactors": [ {"label": true,"type": "hotFileCodeFlow" }, {"label": true,"type": "fixExamples" }]}}],"properties": {"coverage": [{"files": 56,"isSupported": true,"lang": ".java","type": "SUPPORTED"},{"files": 4,"isSupported": true,"lang": ".xml","type": "SUPPORTED"}]},"automationDetails": {"id":"Snyk/Code/2026-06-11T14:02:09Z"}}]}
|