您的服务器颁发的 API 密钥具有与之关联的 CORS 来源。当服务器收到 API 请求时,它会从自定义标头中发送的 API 密钥中检索 CORS 来源并执行 CORS 判断。由于在预检请求期间未发送自定义标头(API 密钥),因此无法执行 CORS 判断。
解决方案是,我们考虑在预检请求时允许任意来源,不做 CORS 判断,在后续的 GET 和 POST 请求中根据 API key 关联的 CORS 来源进行判断,这样会不会存在安全问题?
您的服务器颁发的 API 密钥具有与之关联的 CORS 来源。当服务器收到 API 请求时,它会从自定义标头中发送的 API 密钥中检索 CORS 来源并执行 CORS 判断。由于在预检请求期间未发送自定义标头(API 密钥),因此无法执行 CORS 判断。
解决方案是,我们考虑在预检请求时允许任意来源,不做 CORS 判断,在后续的 GET 和 POST 请求中根据 API key 关联的 CORS 来源进行判断,这样会不会存在安全问题?
我正在迁移一个用 Quarkus 制作的应用程序,并使用 Renarde 作为 UI。我在解决一些与登录表单有关的问题。表单在我使用的旧版 Renarde(3.0.1)上运行良好,但使用新版 Renarde(3.0.19),当我提交表单时,我只得到一个空白页。我试图在代码中设置一个断点,但它甚至没有到达方法。安全性是通过数据库实现的。我很困惑,我真的不知道该怎么做。有人能帮忙吗?为此,我创建了 2 个类
@Provider
@Priority(1)
public class AuthenticationFailedExceptionHandler implements ExceptionMapper<AuthenticationFailedException> {
@Override
public Response toResponse(AuthenticationFailedException exception) {
var removeCookie = new NewCookie.Builder("Authorization")
.value(null)
.path("/")
.domain(null)
.comment(null)
.maxAge(0)
.secure(false)
.httpOnly(true)
.build();
var uri = getURI(Security::login);
return temporaryRedirect(uri).cookie(removeCookie).build();
}
}
和
@ApplicationScoped
public class UserSecuritySetup implements RenardeUserProvider, RenardeOidcHandler {
@Inject RenardeSecurity security;
@Override
public RenardeUser findUser(final String tenantId, final String username) {
return User.findByUsername(username);
}
@Override
public void oidcSuccess(String tenantId, String authId) {
}
@Override
public void loginWithOidcSession(String tenantId, String authId) {
}
}
我的用户实现了 RenardUser
@Entity
@Table(name = "user")
public class User extends PanacheEntity implements RenardeUser {
@Column(name = "code", nullable = false) public String code;
@Column(name = "firstname", nullable = false) public String firstname;
@Column(name = "lastname", nullable = false) public String lastname;
@Column(name = "created_at") public Instant createdAt;
@ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name = "role_id", nullable = false) public Role role;
@ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "status_id", nullable = false) public Status status;
@JsonbTransient @OneToOne(mappedBy = "user") public Credentials credentials;
@OneToOne(mappedBy = "user") public UserPicture picture;
public static User findByCode(String code) {
return User.find("code", code).firstResult();
}
public static User findByUsername(String username) {
return User.find("credentials.username", username).firstResult();
}
@Override
public Set<String> roles() {
Set<String> roles = new HashSet<>();
roles.add(role.code);
return roles;
}
@Override
public String userId() {
return credentials.username;
}
@Override
public boolean registered() {
return true;
}
}
这是用于登录应用程序的类的样子
import com.dwitech.surveille.ui.control.util.Helper;
import com.dwitech.surveille.ui.entity.db.User;
import io.micrometer.core.instrument.MeterRegistry;
import io.quarkiverse.renarde.security.ControllerWithUser;
import io.quarkus.qute.CheckedTemplate;
import io.quarkus.qute.TemplateInstance;
import io.smallrye.common.annotation.Blocking;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;
import org.jboss.resteasy.reactive.RestForm;
import org.mindrot.jbcrypt.BCrypt;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import static com.dwitech.surveille.ui.control.util.CurrentMethod.name;
import static io.quarkiverse.renarde.router.Router.getURI;
import static io.quarkus.elytron.security.common.BcryptUtil.matches;
import static org.jboss.logging.Logger.getLogger;
@Path("/security")
@Blocking
public class Security extends ControllerWithUser<User> {
private static final Logger LOGGER = getLogger(Security.class);
private final MeterRegistry registry;
@ConfigProperty(name = "quarkus.application.name") String applicationName;
@ConfigProperty(name = "quarkus.profile") String profile;
@Inject Helper helper;
@Inject Audit audit;
@Inject DashboardHelper dashboardHelper;
Security(MeterRegistry registry) {
this.registry = registry;
}
public TemplateInstance display_login() {
return sign_in();
}
public TemplateInstance display_change_password(User user) {
return settings()
.data("picture", helper.getPictureAsBase64(user))
;
}
@POST
@Path("login")
public Response login(@RestForm String username, @RestForm String password) {
var action = name();
var user = User.findByUsername(username);
if (user == null || !matches(password, user.credentials.password) || !user.registered()) {
System.out.println("username --> Invalid username/password");
validation.addError("username", "Invalid username/password");
flash.flash("message", "Invalid user: "+username);
prepareForErrorRedirect();
audit.writeAuditLog("LGN", username, action, username, "Invalid username/password");
display_login();
}
var cookie = security.makeUserCookie(user);
String userRole = user.role.code;
System.out.println("userRole --> " + userRole);
audit.writeAuditLog("LGN", username, action, user.credentials.username, "logged in");
var template = dashboardHelper.getDashboard(user);
return Response.ok(template
.data("source", action)
.data("picture", helper.getPictureAsBase64(user))
.data("user", user)
).cookie(cookie).build();
}
@CheckedTemplate(requireTypeSafeExpressions = false)
public static class Templates {
public static native TemplateInstance sign_in();
}
}
这对我来说至关重要。有 2 个应用程序依赖它并且具有相同的行为。
问候并致谢。D.
我是 Keycloak 的新手,正在尝试弄清楚如何使用Keycloack 管理客户端正确注册用户
文档中没有具体的例子,并且缺少大量屏幕截图,从而产生了歧义。
我找到了两个基于 JAVA 的示例,它们提供了一些有关 API 调用应如何工作的见解:这里和这里,但每次我尝试创建用户或查看领域表示时,我都会遇到 jakarta.ws.rs.NotFoundException:HTTP 404 Not Found。有什么帮助可以解释为什么会发生这种情况吗?
我已经创建了客户端凭证客户端,并分配了以下角色以便能够管理用户(创建、删除、修改)。
我能够使用 POSTMAN 中的客户端凭证流从令牌端点接收令牌
下面你会发现 Java 调用
private Keycloak getAdminKeycloak() {
this.base = environment.getProperty(MyConstants.KEYCLOAK_TOKEN_END_POINT);
this.realm = environment.getProperty(MyConstants.KEYCLOAK_REALM);
this.username = environment.getProperty(MyConstants.KEYCLOAK_SERVER_API_CLIENTID);
this.password = environment.getProperty(MyConstants.KEYCLOAK_SERVICE_API_SECRET);
return KeycloakBuilder.builder().serverUrl(base)
.realm(realm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(username)
.clientSecret(password).build();
}
@Override
public ResponseEntity<String> registerUser(User user) {
Keycloak keycloak = getAdminKeycloak();
// set user representation
UserRepresentation newuser = new UserRepresentation();
newuser.setEmail(user.getEmail());
newuser.setFirstName(user.getFirstName());
newuser.setLastName(user.getLastName());
newuser.setEnabled(true);
// Get realm
RealmResource realmResource = keycloak.realm(realm);
System.out.print(realmResource.toRepresentation().toString());
UsersResource usersResource = realmResource.users();
ArrayList<UserRepresentation> users = (ArrayList<UserRepresentation>) usersResource.list();
// create user
Response response = usersResource.create(newuser);
String userID = CreatedResponseUtil.getCreatedId(response);
if (userID == null || userID.isEmpty()) {
return new ResponseEntity<>(MyConstants.ERROR_OCCURED, HttpStatus.METHOD_FAILURE);
}
// set credentials
CredentialRepresentation passwordCred = new CredentialRepresentation();
passwordCred.setTemporary(false);
passwordCred.setType(CredentialRepresentation.PASSWORD);
passwordCred.setValue(user.getPassword());
UserResource userResource = usersResource.get(userID);
userResource.resetPassword(passwordCred);
return new ResponseEntity<>(MyConstants.REGISTRATION_COMPLETE, HttpStatus.OK);
}
我在本地 Linux OS 机器上安装了一个 Splunk 实例版本 9.2.0.1(在 Windows OS 上是通过 WSL 安装的)。前几天,我查看了 $SPLUNK_HOME/etc/login-info.cfg 下的文件(在我的情况下,$SPLUNK_HOME 是 /opt/splunk),它似乎是关于在 Splunk 平台上登录的配置文件。
这是当前的内容:
[admin]
loginAttempts = 0
lastFailedLoginTimestamp = 0.000000
lastSuccessLoginTimestamp = 1723726648.074067
firstFailedLoginTimestamp = 0.000000
我的具体问题是:
这些字段到底是什么意思?似乎没有任何文档说明这一点,这就是我写 Stack Overflow 帖子的原因
该文件的结构是什么?我假设每个用户都有一个单独的节,每个节都以用户名开头,并用方括号括起来,但我不确定,因为缺乏有关此主题的文档。
我做了一些实验,看看这个文件是否以及如何更改。我尝试成功登录,注意到字段 lastSuccessLoginTimestamp 的值随之更改(我猜这是以秒为单位表示的 UNIX 纪元时间)。我甚至故意尝试登录失败。我预计其他字段(loginAttempts、lastFailedLoginTimestamp 和 firstFailedLoginTimestamp)的值会发生变化,但什么也没发生。
无论如何,我不希望配置文件在某些事件发生后发生变化(在本例中,是成功登录)。相反,这是日志文件的行为,应用程序在其中写入正在发生的事件。我认为 .cfg 扩展名具有误导性,但那是另一回事。
NPM 包元数据 JSON 示例如下所示(dist
移至顶部):
{
"name": "lodash",
"version": "4.17.21",
"description": "Lodash modular utilities.",
"dist": {
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"shasum": "679591c564c3bffaae8454cf0b3df370c3d6911c",
"tarball": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"fileCount": 1054,
"unpackedSize": 1412415,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgMS3ZCRA9TVsSAnZWagAA8+4P/jx+SJ6Ue5oAJjz0L7gw\nLDD5YvP8aoliFq4GYkwUXfVQvOwomIPfa+U5Kao/hDfuwFQ/Bq5D5nSsl2bj\nrjJgvlKXna0SId8AgDgY2fB7zSfninuJvalY4iTWMN8DFSpG0XE2QFfoKpd3\njDmuzcNtgr79QV6DgjOVkHiP1IGNDlLTc1QEKiwo/5CdGQi1q/iCj6dViQMJ\nByuuuV2Qzi3f/FI25cG797WZar1MHhhlcnB50HiVBGp54IZOyuqdqWPduZQo\nvhONtonxPGBm3/J+uAkeUSSyL3Ud+FzLvdg8WEI9gDL0yvU4k0FcsnOONEYn\nngLaKEsw2xAnPBYW3Lf73Jnpwx6FAT3k49kgzxiNYSxEo7x4wiuNtBoDMyNw\nEKj6SZ0bUNmaJgiMfDnnDjCKjI3JrO1hho8z6CkwuvxuWLlW9wSsVayggzAI\nEhfeTeISugVHh332oDY2MI/Ysu8MnVN8fGmqeYQBBFj3aWatuA2NvVjACnX/\n54G7FtCU8TxZpm9shFRSopBx8PeI3r+icx1CT8YVFypY416PLnidHyqtME1G\neuRd1nWEz18hvVUAEHmuvHo+EPP3tITmTTUPQcZGMdBcZC+4UBmPMWX466HE\nbHw4aOnUWMa0sWfsERC5xzRZAb4lgMPEoTOnZyN4usMy7x9TzGZKZvU24HUE\nmpae\r\n=NOmG\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIF3Yithbtmy1aEBNlfNWbLswAfPIyQUuNUGARD3Ex2t4AiEA6TlN2ZKJCUpS/Sf2Z6MduF1BNSvayHIpu5wAcICcKXw="
}
]
},
"keywords": [
"modules",
"stdlib",
"util"
],
"homepage": "https://lodash.com/",
"repository": {
"type": "git",
"url": "git+https://github.com/lodash/lodash.git"
},
"icon": "https://lodash.com/icon.svg",
"license": "MIT",
"main": "lodash.js",
"author": {
"name": "John-David Dalton",
"email": "[email protected]"
},
"contributors": [
{
"name": "John-David Dalton",
"email": "[email protected]"
},
{
"name": "Mathias Bynens",
"email": "[email protected]"
}
],
"scripts": {
"test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""
},
"gitHead": "c6e281b878b315c7a10d90f9c2af4cdb112d9625",
"bugs": {
"url": "https://github.com/lodash/lodash/issues"
},
"_id": "[email protected]",
"_nodeVersion": "14.15.5",
"_npmVersion": "6.14.11",
"_npmUser": {
"name": "bnjmnt4n",
"email": "[email protected]"
},
"directories": {
},
"maintainers": [
{
"name": "mathias",
"email": "[email protected]"
},
{
"name": "jdalton",
"email": "[email protected]"
},
{
"name": "bnjmnt4n",
"email": "[email protected]"
}
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/lodash_4.17.21_1613835736675_0.01913912595366596"
},
"_hasShrinkwrap": false
}
以下是我与这 3 个领域相关的问题:
dist.shasum
:据说这是shasum <tarball>
tarball(CLI 命令)的,使用 SHA-1。dist.integrity
:ChatGPT 说(我认为...)这与 具有相同的目的shasum
,但“更安全”(因为有时它使用 SHA-256 或 SHA-512 编码。但是两者的真正区别或原因是什么dist.shasum
和dist.integrity
?它们还有其他区别吗?dist.signatures[*].sig
: 这个签名有什么作用?你如何使用它?ChatGPT 似乎说这是使用公钥进行测试的,但是谁拥有密钥的哪一面,何时使用?你什么时候/为什么会有多个?dist.npm-signature
既然我们也在这里,那么与上述三件事有何关系?
我有时需要编辑敏感文件,例如包含密码或证书的文件。我将 Vim 设置为将交换、备份和撤消文件放在单独的目录中。为了避免 Vim 泄露敏感信息,有没有办法确保 Vim 在调用 Vim/Neovim 编辑特定文件时除了我正在编辑的文件之外不会执行任何其他文件创建或更改?
如果需要,稍微复杂的设置也可以,可能使用 shell 脚本或 shell 别名之类的东西。
为什么 Discord 允许您通过简单的删除请求(例如requests.delete
Python 中的删除请求)删除 Webhook?这不是一个安全问题吗?因为任何人只要有链接就可以删除它?
我刚刚在https://browserleaks.com/webrtc上运行了 WebRTC 泄漏测试
在主报告中,它不包含我的本地 IP,这很好。
但当我仔细查看 时SPD log
,令人惊讶的是,我发现我的本地 ipv6 地址被泄露了SPD log
:
v=0
o=- 100775639648217646 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic: WMS
m=audio 6267 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
c=IN IP4 103.156.242.224
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:366078193 1 udp 2113937151 7bfb0f9a-68de-4774-92b7-c162e8131e84.local 63729 typ host generation 0 network-cost 999
a=candidate:1168470881 1 udp 1677729535 103.156.242.224 6267 typ srflx raddr 0.0.0.0 rport 0 generation 0 network-cost 999
a=ice-ufrag:FoOS
a=ice-pwd:...
...
中a=candidate:
,7bfb0f9a-68de-4774-92b7-c162e8131e84.local
是我的本地 ipv6 地址。
据我所知,浏览器需要我的音频或视频许可才能获取我的本地地址。那么浏览器如何在没有我的权限的情况下获取我的本地IP呢?
有人能给我解释一下吗?提前致谢!
我正在开发一个分布式应用程序,以使用暴力和其他技术来发现密码。
对于暴力破解部分,我需要一个 Rust 密码生成器库或命令行工具。它需要使用特定的字符集、特定的密码长度和范围来生成所有可能性。
能够选择获取特定范围非常重要,因为我打算将这些“密码批次”分发给并行运行的不同工作人员。
例如,生成从第 1001 个到第 2000 个密码的4 位字母数字密码。