# 表情符号被标记为安全

**URL:** https://meta.discourse.org/t/emojis-being-marked-as-secure/257425
**Category:** Bug
**Created:** [2023年三月7日 20:22 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425 "2023-03-07T20:22:01Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月7日 20:22 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/1 "2023-03-07T20:22:01Z")

</div>

我运营的公共网站上的表情符号显示出现问题，访问控制设置为私有，并标记为安全，原因为 `access control post dictates security | source: post creator`。

运行 `uploads:secure_upload_analyse_and_update` 任务可以解决问题，但几天后问题又会出现。网站徽标也曾出现过一次同样的问题，但之后再未发生。

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月9日 00:28 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/3 "2023-03-09T00:28:50Z")

</div>

嘿 @Wolftallemo，当自定义表情符号（或任何可能在帖子中使用的公开可访问的上传）和安全上传结合在一起时，这是一个棘手的问题。很久以前，我们开始使用 `UploadReference` 表来查看什么与什么上传相关联，但是当我们迁移到这个表时，我们将所有 `created_at` 日期时间设置为相同的值。其后果是，当我们出于安全目的检查上传的首次使用是否公开时，有时顺序会出错，我们使用了错误的东西，因为如果两者具有完全相同的 `created_at`，那么 PostgreSQL 就会自行处理：

> <https://github.com/discourse/discourse/blob/008f71b9612db8773befceee2bab6f9fd898c75f/lib/upload_security.rb#L137-L150>

你提到这一点让我再次审视这个问题，我认为我们可以通过按 `created_at ASC` _然后_ `id ASC` 排序来更好地处理这个问题，这样如果存在任何冲突，就应该使用真正的第一个记录。

> <https://github.com/discourse/discourse/pull/20602>
>
> Follow up to 4d2a95ffe6d63b8d2b5019654dd086f6a9bbbd44. Sometimes
> due to the ori…ginal UploadReference migration or other issues,
> multiple UploadReference records can have the exact same
> created\_at date and time. To tiebreak and correct the SQL order
> when this happens, we can add a secondary \`id ASC\` ordering
> when we check for the first upload reference.

如果合并此内容后问题仍然存在（我今天会尝试合并它），并且你已经上传了你的站点，那么我们可以进一步讨论其他选项，但我怀疑这就是你的问题所在。你可以通过执行此操作并比较你站点上的结果来确认：

```ruby
CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC")

CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")

```

第一个应该有一个 `Post` 作为 `target_type`，第二个应该有一个 `CustomEmoji` 作为目标类型。

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月22日 21:14 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/4 "2023-03-22T21:14:15Z")

</div>

它又开始发生了，而且似乎每次都是同一个表情符号。

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [2023年三月23日 02:30 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/7 "2023-03-23T02:30:00Z")

</div>

你能运行 @martin 在上面帖子中分享的查询吗？

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 02:48 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/8 "2023-03-23T02:48:48Z")

</div>

查看结果，我实际上得到了完全相反的结果（第一个返回 `CustomEmoji`，第二个返回 `Post`）

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月23日 02:51 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/9 "2023-03-23T02:51:40Z")

</div>

很有趣，那它返回的是正确的东西。对于链接的上传，你能发布 `security_last_changed_reason` 和 `security_last_changed_at` 的值，看看 `access_control_post_id` 是否已填入？当第一个引用是自定义表情符号时，它不应该将该上传标记为安全。也试试这个：

```ruby
Upload.find(ID)
  .upload_references
  .joins(<<~SQL)
    LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
  SQL
  .where("posts.deleted_at IS NULL")
  .order("upload_references.created_at ASC, upload_references.id ASC")
  .first

```

看看它给你什么记录。

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 03:02 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/10 "2023-03-23T03:02:14Z")

</div>

我收到了 `access control post dictates security | source: post creator`，日期为 `Wed, 22 Mar 2023 09:13:10.341411000 UTC +00:00`。

它为我提供了一个私有分类中三年前创建且从未编辑过的帖子的控制帖子 ID。

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月23日 03:05 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/11 "2023-03-23T03:05:19Z")

</div>

> [@Wolftallemo](#):
>
> 它给了我一个私有类别中三年前创建且从未编辑过的帖子的控制帖子 ID。

有意思，那个帖子使用了自定义表情符号吗？使用上面的上传引用代码和上传 ID 运行时会返回什么？运行此代码并附带上传记录以及发布结果也会有帮助：

```plaintext
UploadSecurity.new(upload).should_be_secure_with_reason

```

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 03:18 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/12 "2023-03-23T03:18:35Z")

</div>

它被用在那个帖子中

查询返回了以下内容：

```plaintext
#<UploadReference:0x0000ffffa6846100
 id: 752,
 upload_id: 236,
 target_type: "Post",
 target_id: 37246,
 created_at: Mon, 25 Nov 2019 22:24:50.002473000 UTC +00:00,
 updated_at: Sun, 29 May 2022 08:13:24.844072000 UTC +00:00
>

```

目标 ID 指向一个根本不包含该表情符号的帖子。

Upload security 返回 `[true, "access control post dictates security"]`

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月23日 03:22 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/13 "2023-03-23T03:22:51Z")

</div>

> [@Wolftallemo](#):
>
> 目标 ID 指向的帖子根本不包含表情符号。

这确实出乎意料，运行这个应该会通过 `UploadReference` 返回与帖子关联的所有上传：

```ruby
UploadReference.where(
    target_type: "Post",
    target_id: 37246,
)

```

如果帖子有引用但 UI 中似乎没有任何上传，那么可能存在迁移问题？

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 03:27 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/14 "2023-03-23T03:27:51Z")

</div>

原来是我把 ID 输错了 :facepalm:

是的，它包含了表情符号，尽管父主题已被删除。

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月23日 03:35 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/15 "2023-03-23T03:35:21Z")

</div>

嗯，没问题。那么如果你用正确的上传再次运行这个，你会得到什么？

```ruby
UploadSecurity.new(upload).should_be_secure_with_reason

```

还有

```ruby
upload
  .upload_references
  .joins(<<~SQL)
    LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
  SQL
  .where("posts.deleted_at IS NULL")
  .order("upload_references.created_at ASC, upload_references.id ASC")
  .first

```

如果真的有必要，你可以将 `CustomEmoji` `UploadReference` 记录的 `created_at` 日期和时间设置为比该上传的任何其他 `UploadReference` 记录更早的时间，但你实际上不必这样做。

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 03:42 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/16 "2023-03-23T03:42:47Z")

</div>

我应该澄清一下。上传 ID 是正确的，但帖子 ID 不正确（这也是我最终导致帖子不包含表情符号的原因——我在这里粘贴的是正确的，但我在查找时输入错误了）

所有其他命令仍然返回相同的内容

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年三月23日 04:03 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/17 "2023-03-23T04:03:53Z")

</div>

如果是这种情况，那么日期确实有些奇怪，可能是由我们的自动迁移引起的。运行这个：

```plaintext
CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")

```

找到 `target_type: "CustomEmoji"` 的 `UploadReference` 记录，然后执行：

```ruby
UploadReference.find(ID).update!(created_at: UploadReference.find(752).created_at - 1.day))

```

然后对有问题的上传运行这个：

```ruby
upload.update_secure_status

```

这样应该就能解决了……我真的认为这主要会是迁移后旧上传的问题。你还可以做的另一件事是删除自定义表情符号，重新上传它，然后运行：

```ruby
Jobs.enqueue(:rebake_custom_emoji_posts, name: EMOJI_NAME)

```

不过更新日期会更容易一些。抱歉给你添麻烦了！

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年三月23日 04:11 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/18 "2023-03-23T04:11:47Z")

</div>

目前的表情符号不再安全 :meow_heart:

我想几天后就会知道它是否真的有效了。

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [2023年四月15日 11:33 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/19 "2023-04-15T11:33:29Z")

</div>

嘿 @Wolftallemo 🙂

你这个问题解决了吗？

---

<div class="post-metadata">

### Author: ![Wolftallemo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wolftallemo/32/289645_2.png) [@Wolftallemo](https://meta.discourse.org/u/Wolftallemo)
#### Post date: [2023年四月16日 04:13 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/20 "2023-04-16T04:13:41Z")

</div>

还没有东西坏掉

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [2023年四月16日 23:30 UTC](https://meta.discourse.org/t/emojis-being-marked-as-secure/257425/23 "2023-04-16T23:30:33Z")

</div>


