• 151 主题
    199 帖子

    你还在为找不到工作而苦恼吗?来,看这里,这里有成千上万的工作,只要你有能力,里面的工作都是你的,你可以兼职,也可以全职,时间自由,只要你想工作了,就进来。。。
    你还为每天上下班时间太长而整体没有精神吗?来,看这里,这里是远程办公,你可以不用挤公交,挤地铁,不用怕塞车;你可以睡到自然醒,元气满满的开始你一天的工作。。。
    你还在为下班的时候老板叫你加班或开会而不爽吗?来,看这里,这里只需要你在规定时间内完成任务即可。。。
    是不是很爽,这里就是云队友远程工作平台,是一个提供远程工作求职,远程用人管理的平台。目前,平台有数十万优质人才提供远程工作服务,也有大量远程全职/兼职的职位。平台包涵技术、运营、设计、产品、HR、翻译等多类目职位,满足企业的远程用人需求和人才的远程工作需求。
    加入我们吧!
    https://www.duiyou360.com/?utm_source=user11
    3d40f5f6-a4d7-4713-ad00-53d1ab59fdae-image.png

  • 64 主题
    223 帖子

    @drw2005 已修复

  • 11 主题
    29 帖子
  • 3 主题
    7 帖子

    首先要了解下discuzX3.4和nodebb的数据库结构,discuzX用的是mysql,nodebb用的是mongodb。

    最重要的当然是用户相关的数据表和帖子数据表。discuzX能查到数据表字典,nodebb只能自己用mongodb的admin工具看了。

    一、用户数据

    1、nodebb和discuz数据表的对照

    Nodebb用户表须用的数据(字段): db.objects.findOne({username:"admin"}) --> { "_id" : ObjectId("65cb8801e09f69ff71141520"), "_key" : "user:1", "joindate" : 1707837441083, "lastonline" : 1708000177292, //"status" : "online", "uid" : 1, "username" : "admin", //"userslug" : "admin", "password" : "$2a$12$VIKLGFC3AS1B4sDuVNivIOQO1HVpxjdOJXyUDBnDZqbu5nK", //"password:shaWrapped" : 1, "email" : "32342@yeah.net", //"email:confirmed" : 1, //"groupTitle" : "[\"\"]", //"gdpr_consent" : 1, "profileviews" : 0, // 空间点击数 views "reputation" : 0, // 声誉,积分 credits "topiccount" : 1, // 主题 threads "lastposttime" : 1707837441933, "postcount" : 1, // 帖子 posts (包含了主题) //"rss_token" : "17305070-9558-4f2a-bef1-aba7902e0990", "picture" : "/assets/uploads/profile/1-profileavatar-1707989852545.jpeg", "uploadedpicture" : "/assets/uploads/profile/1-profileavatar-1707989852545.jpeg", "fullname" : "全名guojin", "aboutme" : "关于我是一个管理员", "birthday" : "2024-02-15", "location" : "广州", "signature" : "签名:我是一个管理员", "website" : "https://weibo.com/我的网" }

    discuzX 的表分得比较散,有好几个表:

    pre_common_member 用户主表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 会员id email char(40) NO 邮箱 username char(15) NO 用户名 password char(32) NO 密码 status tinyint(1) 0 NO 判断用户是否已经删除 需要discuz程序加判断,并增加整体清理的功能。原home字段为flag emailstatus tinyint(1) 0 NO email是否经过验证 home字段为emailcheck avatarstatus tinyint(1) 0 NO 是否有头像 home字段为avatar videophotostatus tinyint(1) 0 NO 视频认证状态 home adminid tinyint(1) 0 NO 管理员id groupid smallint(6) unsigned 0 NO 会员组id groupexpiry int(10) unsigned 0 NO 用户组有效期 extgroupids char(20) NO 扩展用户组 regdate int(10) unsigned 0 NO 注册时间 credits int(10) 0 NO 总积分 notifysound tinyint(1) 0 NO 短信声音 timeoffset char(4) NO 时区校正 newpm smallint(6) unsigned 0 NO 新短消息数量 newprompt smallint(6) unsigned 0 NO 新提醒数目 accessmasks tinyint(1) 0 NO 标志 allowadmincp tinyint(1) 0 NO 标志 onlyacceptfriendpm tinyint(1) 0 NO 是否只接收好友短消息 conisbind tinyint(1) unsigned 0 NO 用户是否绑定QC

    uc_members 用户表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 用户ID username char(15) NO 用户名 password char(32) NO 密码 email char(32) NO 用户Email myid char(30) NO 漫游id myidkey char(16) NO 漫游id regip char(15) NO 注册IP regdate int(10) unsigned 0 NO 注册时间 lastloginip int(10) 0 NO 上次登陆的IP(程序转换成数值类型) lastlogintime int(10) unsigned 0 NO 上次登录的时间 salt char(6) NO 密码干扰串,用来和密码进行配合验证,防止被暴力破解 secques char(8) NO 用户的安全提问

    pre_common_member_field_forum 用户论坛字段表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 会员id publishfeed tinyint(3) 0 NO 用户自定义发送哪些类型的feed(原字段为customaddfeed) customshow tinyint(1) unsigned 26 NO 自定义帖子显示模式 customstatus varchar(30) NO 自定义头衔 medals text NO 勋章信息 sightml text NO 签名 groupterms text NO 公共用户组 authstr varchar(20) NO 找回密码验证串 groups mediumtext NO 用户所有群组 attentiongroup varchar(255) NO 用户偏好

    pre_common_member_profile 用户栏目表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 会员id realname varchar(255) NO 实名 gender tinyint(1) 0 NO 性别 (0:保密 1:男 2:女) birthyear smallint(6) unsigned 0 NO birthmonth tinyint(3) unsigned 0 NO birthday tinyint(3) unsigned 0 NO constellation varchar(255) NO 星座(根据生日自动计算) zodiac varchar(255) NO 生肖(根据生日自动计算) telephone varchar(255) NO 固定电话 mobile varchar(255) NO 手机 idcardtype varchar(255) NO 证件类型:身份证 护照 军官证等 idcard varchar(255) NO 证件号码 address varchar(255) NO 邮寄地址 zipcode varchar(255) NO 邮编 nationality varchar(255) NO 国籍 birthprovince varchar(255) NO 出生省份 birthcity varchar(255) NO 出生城市 birthdist varchar(20) NO 出生行政区/县 birthcommunity varchar(255) NO 出生小区 resideprovince varchar(255) NO 居住省份 residecity varchar(255) NO 居住城市 residedist varchar(20) NO 居住行政区/县 residecommunity varchar(255) NO 居住小区 residesuite varchar(255) NO 小区、写字楼门牌号 graduateschool varchar(255) NO 毕业学校 company varchar(255) NO 公司 education varchar(255) NO 学历 occupation varchar(255) NO 职业 position varchar(255) NO 职位 revenue varchar(255) NO 年收入 affectivestatus varchar(255) NO 情感状态 lookingfor varchar(255) NO 交友目的(交友类型) bloodtype varchar(255) NO 血型 height varchar(255) NO 身高 weight varchar(255) NO 体重 alipay varchar(255) NO 支付宝帐号 icq varchar(255) NO ICQ qq varchar(255) NO QQ yahoo varchar(255) NO YAHOO msn varchar(255) NO MSN taobao varchar(255) NO 阿里旺旺 site varchar(255) NO 主页 bio text NO 自我介绍 来自论坛bio字段 interest text NO 兴趣爱好 field1 text NO 自定义字段1 field2 text NO 自定义字段2 field3 text NO 自定义字段3 field4 text NO 自定义字段4 field5 text NO 自定义字段5 field6 text NO 自定义字段6 field7 text NO 自定义字段7 field8 text NO 自定义字段8

    pre_common_member_count 用户统计表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 会员id extcredits1 int(10) 0 NO 声望 extcredits2 int(10) 0 NO 金钱 extcredits3 int(10) 0 NO 扩展 extcredits4 int(10) 0 NO 扩展 extcredits5 int(10) 0 NO 扩展 extcredits6 int(10) 0 NO 扩展 extcredits7 int(10) 0 NO 扩展 extcredits8 int(10) 0 NO 扩展 friends smallint(6) unsigned 0 NO 好友个数 home posts mediumint(8) unsigned 0 NO 帖子数 threads mediumint(8) unsigned 0 NO 主题数 digestposts smallint(6) unsigned 0 NO 精华数 doings smallint(6) unsigned 0 NO 记录数 blogs smallint(6) unsigned 0 NO 日志数 albums smallint(6) unsigned 0 NO 相册数 sharings smallint(6) unsigned 0 NO 分享数 attachsize int(10) unsigned 0 NO 上传附件占用的空间 home views mediumint(8) unsigned 0 NO 空间查看数 oltime smallint(6) unsigned 0 NO 在线时间 todayattachs smallint(6) unsigned 0 NO 当天上传附件数 todayattachsize int(10) unsigned 0 NO 当天上传附件容量 feeds mediumint(8) unsigned 0 NO 广播数 follower mediumint(8) unsigned 0 NO 听众数量 following mediumint(8) unsigned 0 NO 收听数量 newfollower mediumint(8) unsigned 0 NO 新增听众数量 blacklist mediumint(8) unsigned 0 NO 拉黑用户数

    pre_common_member_status 用户状态表

    字段名 数据类型 默认值 允许非空 备注 uid mediumint(8) unsigned NO 会员id regip char(15) NO 注册IP lastip char(15) NO 最后登录IP lastvisit int(10) unsigned 0 NO 最后访问 lastactivity int(10) unsigned 0 NO 最后活动 lastpost int(10) unsigned 0 NO 最后发表 lastsendmail int(10) unsigned 0 NO 上次发送email时间 home原字段为lastsend invisible tinyint(1) 0 NO 是否隐身登录 buyercredit smallint(6) 0 NO 买家信用等级及积分 sellercredit smallint(6) 0 NO 卖家信用等级及积分 favtimes mediumint(8) unsigned 0 NO 个人空间收藏次数 sharetimes mediumint(8) unsigned 0 NO 个人空间分享次数 profileprogress tinyint(2) unsigned 0 NO 个人资料完成度

    2、处理头像

    discuz 默认自定义头像目录:data/attachment/forum/pw/upload/33370.jpg

    discuzX的默认自定议头像目录:

    /uc_server/data/avatar/000/xx/xx/xx_avatar_middle.jpg

    其中 xx/xx/xx_ 正好是 uid,位数不够的系统会自动补零

    因此写了个程序,把xx_avatar_middle.jpg文件拷贝到一个目录里(一会儿复制到服务端去),并把文字名改为 xxxxxx_avatar_middle.jpg,最后还把{uid: “xxxxxx”, path: "/assets/uploads/profile/000/dz_avatar/62011_avatar_middle.jpg”} 存成json文件,以备后面使用。

    服务端我复制到目录:~/nodebb/public/uploads/profile/dz_avatar

    import os,shutil,json # file_list 为文件名称列表 def find_files_path(str_list, path=r"./"): # 组合绝对路径,当前路径+目录 whole_path = os.getcwd() + path # 遍历目录下的文件 files_path = os.walk(whole_path) # 路径空列表,用来存储查找文件路径 path_data = [] try: # 遍历要寻找的文件 for str in str_list: # 查找目录下对应的文件 for root, dirs, files in files_path: # 遍历所有文件名称,添加符合文件名称的文件路径进列表 for f in files: if str in f: real_path = (root + "\\" + f).replace("./", "\\") #print(real_path) uid_file = real_path[-26:].replace("\\", "").lstrip("0") #去0,得到文件名:uid + _avatar_middle.jpg path_data.append({"uid": real_path[-26:-18].replace("\\", "").lstrip("0"), "path": '/assets/uploads/profile/dz_avatar/'+uid_file}) shutil.copyfile(real_path, "./" + uid_file) # 拷贝文件 except Exception as e: print("遍历出现错误:" + e) finally: return path_data uid_file_list = find_files_path(["big"], "./") print(uid_file_list) #data = {'name': 'John', 'age': 30, 'city': 'New York'} with open('avatar_data.json', 'w') as f: json.dump(uid_file_list, f)
  • 摸鱼 、讨论、创意分享

    238 主题
    485 帖子

    感谢分享

  • 技术交流

    216 主题
    471 帖子

    防止 API 中的漏洞

    在设计 API 时,请确保从一开始就考虑安全性。特别是,请确保您:

    如果您不希望公开访问 API,请保护您的文档。 确保您的文档保持最新状态,以便合法测试人员能够全面了解 API 的攻击 表面。 应用允许的 HTTP 方法的允许列表。 验证每个请求或响应的内容类型是否为预期。 使用通用错误消息来避免泄露可能对攻击者有用的信息。 对 API 的所有版本(而不仅仅是当前生产版本)使用保护措施。

    若要防止批量分配漏洞,请将用户可更新的属性列入允许列表,并将用户不应更新的敏感属性列入黑名单。

    服务器端参数污染

    某些系统包含无法从 Internet 直接访问的内部 API。当网站在没有充分编码的情况下将用户输入嵌入到对内部 API 的服务器端请求中时,就会发生服务器端参数污染。这意味着攻击者可能能够操纵或注入参数,从而使他们能够,例如:

    覆盖现有参数。 修改应用程序行为。 访问未经授权的数据。

    您可以测试任何用户输入的任何类型的参数污染。例如,查询参数、表单字段、标头和 URL 路径参数都可能容易受到攻击。
    d1f61ad4-88a9-478e-86b4-6793c731c1db-image.png

    注意 此漏洞有时称为 HTTP 参数污染。但是,此术语也用于指 Web 应用程序防火墙 (WAF) 绕过技术。为避免混淆,在本主题中,我们将仅提及服务器端参数污染。 此外,尽管名称相似,但此漏洞类与服务器端几乎没有共同之处 原型污染。

    测试查询字符串中的服务器端参数污染

    若要测试查询字符串中的服务器端参数污染,请在输入中放置查询语法字符(如 #、& 和= ),并观察应用程序的响应方式。

    考虑一个易受攻击的应用程序,它使您能够根据其他用户的用户名搜索其他用户。当您搜索用户时,您的浏览器会发出以下请求:

    GET /userSearch?name=peter&back=/home

    为了检索用户信息,服务器使用以下请求查询内部 API:

    GET /users/search?name=peter&publicProfile=true

    截断查询字符串

    您可以使用 URL 编码的字符来尝试截断服务器端请求。为了帮助您解释响应,您还可以在字符后添加一个字符串。##

    例如,可以将查询字符串修改为以下内容:

    GET /userSearch?name=peter%23foo&back=/home

    前端将尝试访问以下 URL:

    GET /users/search?name=peter#foo&publicProfile=true 注意 对字符进行 URL 编码至关重要。否则,前端应用程序会将其解释为片段标识符,并且不会将其传递给内部 API。#

    查看响应,以获取有关查询是否已被截断的线索。例如,如果响应返回 user ,则服务器端查询可能已被截断。如果返回错误消息,则应用程序可能已被视为用户名的一部分。这表明服务器端请求可能尚未被截断。peterInvalid namefoo

    如果能够截断服务器端请求,则无需将字段设置为 true。您可以利用此漏洞返回非公开用户配置文件。publicProfile

    注入无效参数

    您可以使用 URL 编码字符尝试向服务器端请求添加第二个参数。&

    例如,可以将查询字符串修改为以下内容:

    GET /userSearch?name=peter%26foo=xyz&back=/home

    这会导致对内部 API 发出以下服务器端请求:

    GET /users/search?name=peter&foo=xyz&publicProfile=true

    查看响应,以获取有关如何分析其他参数的线索。例如,如果响应未更改,这可能表示该参数已成功注入,但被应用程序忽略。

    为了建立更完整的画面,您需要进一步测试。

    注入有效参数

    如果能够修改查询字符串,则可以尝试向服务器端请求添加第二个有效参数。

    相关页面
    有关如何识别可注入查询字符串的参数的信息,请参阅查找隐藏 parameters 部分。

    例如,如果已标识该参数,则可以将其添加到查询字符串中,如下所示:email

    GET /userSearch?name=peter%26email=foo&back=/home

    这会导致对内部 API 发出以下服务器端请求:

    GET /users/search?name=peter&email=foo&publicProfile=true

    查看响应,以获取有关如何分析其他参数的线索。

    覆盖现有参数

    若要确认应用程序是否容易受到服务器端参数污染的影响,可以尝试覆盖原始参数。为此,请注入具有相同名称的第二个参数。

    例如,可以将查询字符串修改为以下内容:

    GET /userSearch?name=peter%26name=carlos&back=/home

    这会导致对内部 API 发出以下服务器端请求:

    GET /users/search?name=peter&name=carlos&publicProfile=true

    内部 API 解释两个参数。其影响取决于应用程序如何处理第二个参数。这在不同的 Web 技术中有所不同。例如:name

    PHP 只解析最后一个参数。这将导致用户搜索 .carlos
    ASP.NET 结合了这两个参数。这将导致用户搜索 ,这可能会导致错误消息。peter,carlosInvalid username
    Node.js / express 仅解析第一个参数。这将导致用户搜索 ,给出不变的结果。peter
    如果您能够覆盖原始参数,则可以进行攻击。例如,您可以添加到请求中。这可能使您能够以管理员用户身份登录。name=administrator

  • 源码分享

    110 主题
    177 帖子
    DuckDB

    Duck是什么?DuckDB is a fast in-process analytical database。

    DuckDB 是一个主要用于分析的DBMS数据库,支持丰富的SQ。借鉴SQLite的成功经验,使用C++开发,设计的非常轻量级,就一个二进制文件没有其他依赖(压缩后仅8M大小),但性能可不小。

    1. 安装DuckDB

    DuckDB 可直接嵌入到主流编程语言中,提供 Python、R、Java、Node.js 、Go、C++等依赖库。

    也提供cli命令行工具,直接在Windows、Linux、macOS 系统中运行。下载后就一个二进制文件,不需要安装直接运行,没有其他依赖使用非常方便。

    2. 使用DuckDB

    为了方便演示我们直接使用命令行方式运行DuckDB

    ./duckdb Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database.

    执行 duckdb 命令,数据库就运行起来了。注意没有其他后台服务,不用像MySQL等需要区分server和client。

    duckdb 支持内存运行模式,和持久化两种模式。默认就是内存模式,退出进程后数据就没了哈。持久化需要指定数据文件路径。

    3. 查询测试

    DuckDB 支持从CSV、JSON、parquet中导入数据,也可通过HTTP、S3远程导入。还提供各种插件直连MySQL、Iceberg、PostgreSQL 等导入。这点和 clickhouse 一样,非常人性化方便。

    这里我们使用CSV,导入GitHub数据,共8百万条数据。不到1秒就完成数据导入和查询了,非常牛逼。

    SELECT COUNT(*) FROM gharchive.csv.gz

    注意这里导入的文件使用了gzip压缩文件,DuckDB 能自动帮我们解压非常方便。

    最后DuckDB仓库地址,https://github.com/duckdb/duckdb